views:

112

answers:

2

How do you change the behavior of a QListWidget so that it resizes its height instead of choosing a (seemingly arbitrary) height and adding scrollbars? See screenshot:

screen shot

The QListView's should fill up as much space horizontally as they can (creating as many "columns," if you will.) Then they wrap and make as many rows as necessary to fit all the items. These calculations should be adjusted as the window is resized. This is all working fine.

However, what I want to happen is that instead of the height staying the same, the QListView should grow or shrink vertically and never need any scrollbars. The scrolling, if necessary, will be handled on the parent QWidget that hosts all of the labels and lists. It seems like once the height of the QListWidget is established (not sure where its default is coming from), it never changes. It is too big in some cases (see second "Test" list above) and too small in others (see first "blank maps" list above.)

The layout above is nothing surprising: two QLabel's and two QListWidget's in a QVBoxLayout. Here are the properties I have set on the QListWidget's:

setMovement(QListView::Static);
setResizeMode(QListView::Adjust);
setViewMode(QListView::IconMode);
setIconSize(QSize(128, 128));

(I already tried setting the horizontal and vertical scrollbar policies, but that just turns the scrollbars off, clipping the content. Not what I want.)

A: 

There is a protected member function called contentsSize() in QListView. It is used to calculate the required minimum(), maximum(), and pageStep() for the scrollbars (as mentioned here).

Can you subclass the QListView class and make use of that information? I suggest you recalculate the size of your widget in the same function where you add contents to it. While somewhat lacking elegance, this appears to be a pretty reliable solution.

David Parunakian
That property looks helpful, but I'm really not sure how to use it. With that size, what method can I call on the QListWidget to force it to be that value? (Or change the sizeHint?) Sorry, relatively new to Qt here, and this is very obscure to me. Thanks for your help!
Dave
You can set `sizeHint` to this size and set the `sizeHintPolicy` to `Fixed`; or use the `setGeometry()` method. Disclaimer: I didn't test what I'm proposing here, but I'm pretty confident that it will work.
David Parunakian
+2  A: 

Maybe you could this without using QListWidget. The Qt's examples contain a new layout class, QFlowLayout, which could be useful. With the following kind of widget hierarchy you could get multiple groups with labels and they all would be inside one QScrollArea.

QScrollBox
  QVBoxLayout

    QLabel "Blank maps"
    QWidget
       QFlowLayout
          your own widgets showing map images and labels

    QLabel "Text"
    QWidget
       QFlowLayout
          your own widgets

The problem is that this kind of solution would create much more widgets than QListWidget based solution. So if you have hundreds of items in your list, this might not be the best solution.

Roku
OK, this is very, very close. It works great as long as the QScrollBox isn't in the picture. As soon as I add that, the QVBoxLayout gets as skinny as it can and as long as it can. (It is returning sizeHint of QSize(197, 942). I have tried every combination of QWidget::setSizePolicy and QLayout::setSizeConstraint that I can think of, and nothing is changing that behavior. What is the secret?
Dave
`QScrollArea::setWidgetResizable()` FOR. THE. WIN!!!Thank you so much for your help ... I lost 2 days doing down that `QListWidget` rabbit trail.
Dave