PDA

View Full Version : QTreeWidget minimum height



Alundra
14th November 2014, 23:54
Hi,
I have a layout with QTreeWidget but that expands I would have a fixed size to have the minimum size to show all item inside the tree.
I have a QScrollArea with the layout inside it, the problem is I have the tree which takes all the place, I would have only the minimum space needed to show all items.
I have tried a lot of way but no one worked correctly.
How can I achieve this result ?
Thanks for the help

wysota
15th November 2014, 07:54
calculate the size (including the header and frames), return it from size hint and set the size policy to Fixed or Preferred.

Alundra
18th November 2014, 04:09
The only way I found is to set the size policy :

setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );
And use this sizeHint :

QSize CPropertyEditorWidget::sizeHint() const
{
// Iterator of all items.
QTreeWidgetItemIterator AllIterator( m_TreeWidget, QTreeWidgetItemIterator::All );

// Height of all item and header.
int Height = m_TreeWidget->header()->height() + 2;

// While iterator is valid.
while( *AllIterator )
{
// Update the height.
QTreeWidgetItem* Item = *AllIterator;
Height += m_TreeWidget->visualItemRect( Item ).height();

// Next iterator.
++AllIterator;
}

// Return the size hint.
return QSize( m_TreeWidget->sizeHint().width(), Height );
}
There is a way to avoid the "+ 2" in this line ?

int Height = m_TreeWidget->header()->height() + 2;
Thanks for the help

EDIT:
The code before is not perfect on all situation, I have changed using "setFixedHeight( Height );" when one item is added but if the widget use the size policy Expanding when one item is added the siz policy change to fixed on height because of "setFixedHeight( Height );", that looks like a not easy problem to solve.

wysota
18th November 2014, 10:00
+2 comes from the frame size. You should use QStyle::styleHint() to ask the style for the proper frame size of your style.

Alundra
18th November 2014, 14:02
I have found an easy way to handle my problem, I have a SetFixedHeightToShowAllItems() and I set the size policy to fixed when needed.
About the frame width I only found this one, all other are for specific widget but not the tree :

const int FrameWidth = m_TreeWidget->style()->styleHint( QStyle::StyleHint::SH_WindowFrame_Mask );
That return the value 1, I guess it's normal because there is one border on top and one on bottom so that's (2*FrameWidth).
Is it the correct styleHint or that can cause problems ?

wysota
18th November 2014, 14:08
Hmm... actually I think I told you wrong. You should use pixelMetric() with PM_DefaultFrameWidth or alike.

Alundra
18th November 2014, 19:43
ok Thanks, I have changed like that :


void CPropertyEditorWidget::SetFixedHeightToShowAllProp erties()
{
// Iterator of all items.
QTreeWidgetItemIterator AllIterator( m_TreeWidget, QTreeWidgetItemIterator::All );

// Initialize the SpinBox style option.
const int FrameWidth = m_TreeWidget->style()->pixelMetric( QStyle::PM_DefaultFrameWidth );

// Height of all item and header.
int Height = m_TreeWidget->header()->height() + (2 * FrameWidth);

// While iterator is valid.
while( *AllIterator )
{
// Update the height.
QTreeWidgetItem* Item = *AllIterator;
Height += m_TreeWidget->visualItemRect( Item ).height();

// Next iterator.
++AllIterator;
}

// Set the fixed height.
setFixedHeight( Height );
}

wysota
18th November 2014, 22:22
Wouldn't it be easier to query for the visual rect of the last item only? You could then take its bottom() value.

Alundra
19th November 2014, 02:53
I have tried :


void CPropertyEditorWidget::SetFixedHeightToShowAllProp erties()
{
const int FrameWidth = m_TreeWidget->style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
const int LastItemBottom = m_TreeWidget->visualItemRect( m_TreeWidget->topLevelItem( m_TreeWidget->topLevelItemCount() - 1 ) ).bottom();
setFixedHeight( m_TreeWidget->header()->height() + ( 2 * FrameWidth ) + LastItemBottom );
}

But that doesn't work, I have the scrollbar on the right, using the iterator version the scrollbar is not visible.

wysota
19th November 2014, 03:04
Due to how bottom() is interpreted (see the docs) you should add 1 to it.

Alundra
19th November 2014, 16:12
Note that for historical reasons this function returns top() + height() - 1; use y() + height() to retrieve the true y-coordinate.
I have added the +1 on the "bottom()" version and that works good, thanks for the comment on bottom(), this version is faster surely.

wysota
19th November 2014, 18:51
Just keep in mind your code will not work for trees where items have children. You'd have to recursively descend to the deep-most visible child of the last item.