PDA

View Full Version : QTreeWidget fixed column size



Alundra
7th January 2015, 04:28
Hi,
I want to add an additional icon in the QTreeItem to have option to set something visible or not when clicking on the icon.
I have tried the delegate but the text of the item go behind the icon and I didn't found a way to have the "..." before the icon.
Here the code of the delegate :


class CItemDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:

CItemDelegate( QObject* Parent = NULL ) :
QStyledItemDelegate( Parent )
{
m_VisibleIcon = QPixmap( QIcon( "Images/Visible.png" ).pixmap( 20, 20 ) );
}

void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QStyledItemDelegate::paint( painter, option, index );
painter->drawPixmap( ComputeVisibleIconPos( option ), m_VisibleIcon );
}

bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
{
if( event->type() == QEvent::MouseButtonRelease )
{
QMouseEvent* MouseEvent = static_cast< QMouseEvent* >( event );
const QRect VisibleButtonRect = m_VisibleIcon.rect().translated( ComputeVisibleIconPos( option ) );
if( VisibleButtonRect.contains( MouseEvent->pos() ) )
emit VisibleIconClicked( index );
}
return false;
}

signals:

void VisibleIconClicked( const QModelIndex& );

private:

QPoint ComputeVisibleIconPos( const QStyleOptionViewItem& option ) const
{
return QPoint( option.rect.right() - m_VisibleIcon.width() - 2,
option.rect.center().y() - m_VisibleIcon.height() / 2 );
}

private:

QPixmap m_VisibleIcon;
};

The second option is to have 2 columns but I didn't found a way to have the second column fixed width and the first column stretch correctly.
The second column could have a QToolButton with a stylesheet on it to only show the image.
I tried to have the icon on the first column and text on the second but decoration didn't worked good because I didn't found a way to have it on the second column.
The delegate version is more clean because a no name column is not needed.
How can I have the "..." before the icon ?
If the solution is to have icon before the icon already on the item, i like the solution but I don't know how do it.
Thanks for the help

Alundra
7th January 2015, 17:44
I have tried :


void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QStyleOptionViewItem NewOption = option;
NewOption.rect.setWidth( NewOption.rect.width() - m_VisibleIcon.width() - 2 );
QStyledItemDelegate::paint( painter, NewOption, index );
painter->drawPixmap( ComputeVisibleIconPos( option ), m_VisibleIcon );
}

That works but the row selection color stops before the icon, that's the last issue.

danki
5th February 2015, 15:06
Hi,
looking for a long time the web to fix a column width in a QTreeWidget, i finally found a workaround like that:

Derive your own class from QTreeWidget, and implement a slot to handle the resize signals emitted by the QHeaderView.



class MyTreeWidget : public QTreeWidget
{
Q_OBJECT

public:
explicit MyTreeWidget( QWidget *parent = 0 );
...

protected slots:
void onSectionResized ( int column, int oldSize, int newSize );
...

};


In the implementation file


MyTreeWidget::MyTreeWidget( QWidget *parent ) : QTreeWidget( parent )
{
// reconnect the QHeaderView signal sectionResized to be managed by our class
QHeaderView headerView = header();
disconnect( headerView, SIGNAL(sectionResized(int,int,int)) );
connect( headerView, SIGNAL(sectionResized(int,int,int)), SLOT(onSectionResized(int,int,int)) );
...
}

void MyTreeWidget::onSectionResized ( int column, int oldSize, int newSize )
{
// Set the first column width fixed
if( column <= 1 )
{
if( columnWidth( 0 ) != indentation() * 2 )
setColumnWidth( 0, indentation() * 2 );
}
else
QTreeWidget::columnResized( column, oldSize, newSize );
}


Notice that the column width is set only one time;

I hope this could help