Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Lost on resizing QListWidget :(



  • How to get this QListWidget to resize to fit the contents?
    Here's my code:

    #include <QApplication>
    #include <QListWidget>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QListWidget w;
        QStringList items = {"One", "Two", "Three"};
        w.addItems(items);
        w.adjustSize();
    
        w.show();
        return a.exec();
    }
    

    Which shows:
    374e96ad-ed87-4978-8550-525b09eb9915-image.png

    This window needs to be the same size as the containing text, like this:
    4772bcd6-956c-4476-ad5a-04500a9e38ab-image.png
    Or, when there's longer items, something like this:
    b93c610a-71d5-44cf-8209-bd3ad0fbb62a-image.png

    I did think adjustSize() was all that I required.
    What command is required to adjust the size to the contents (horizontally)?



  • This is my final solution for anyone else out there wondering why their list will not 'fit to content':

    #include <QApplication>
    #include <QListWidget>
    #include <QDebug>
    #include "listwidget.h"
    
    class ListWidget : public QListWidget
    {
    public:
        explicit ListWidget(QWidget *parent = nullptr):QListWidget(parent){}
        ~ListWidget(){}
    
        QSize sizeHint() const
        {
            QSize size = QListWidget::sizeHint();
            auto column_width = sizeHintForColumn(0);
            auto frame_width = frameWidth();
            auto margins = contentsMargins();
            auto new_width = column_width+frame_width + margins.left()+margins.right();
            size.setWidth(new_width);
    
            return size;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        ListWidget w;
        QStringList items = {"C2H6O - Ethanol",
                             "CHCl - Trichloromethane",
                             "CO2 - Carbon Dioxide",
                             "H2O - Water",
                             "NaCl - Sodium Choride",
                             "NH3 - Ammonia"  };
        w.addItems(items);
        w.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
        w.show();
        return a.exec();
    }
    

    Which looks like this:
    6182b3f5-70e8-4d71-9bbf-3c9b760e4094-image.png


  • Lifetime Qt Champion

    @idlefrog said in Lost on resizing QListWidget :(:

    w.adjustSize();

    Try to call this after w.show()



  • @jsulm
    I have a question on this, which I have never understood fully in Qt widgets. Instead of having to call adjustSize() on showing/resizing/whatever (and btw here, is it necessary to call adjustSize() in the show/resize event, not just after w.show() which only sets a flag for show), is it not possible to set a size policy which would make Qt do this for you automatically? Or, is this not possible because it's a QListWidget?



  • @jsulm
    Adding w.adjustSize() after w.show() has no effect. It looks exactly the same.


  • Lifetime Qt Champion

    @JonB I think you're right. Calling show() does not yet show anything and so does not size the widgets.
    @idlefrog Try to play with sizePolicy of your widget.



  • Here's my brute force solution:

    #include <QApplication>
    #include <QListWidget>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QListWidget w;    
        QStringList items = {"CO2 - Carbon Dioxide", "H2O - Water", "NaCl - Sodium Choride", "NH3 - Ammonia" };
        w.addItems(items);
    
        auto column_width = w.sizeHintForColumn(0);
        auto widget_size = w.sizeHint();
        auto frame_width = w.frameWidth();
        auto margins = w.contentsMargins();
        auto new_width = column_width+frame_width + margins.left()+margins.right();
        
        widget_size.setWidth(new_width);
        w.resize(widget_size);
    
        w.show();
    
        return a.exec();
    }
    

    Which looks like this:
    6f264df9-7c69-402d-b2cb-adb41e72c197-image.png

    I'll try the size policy next :)



  • @jsulm
    I've tried every size policy, but none make any useful difference.
    It seems that QListWidget does not support an 'adjust to fit contents'.

    There is a setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents), but that doesn't respect the size of the items in the list.



  • This will do it.
    QFont font = w->font(); /*get default font */
    QRectF fontBoundRect = QFontMetrics( font ).tightBoundingRect( the longst string );
    w->setFixedWidth( fontBoundRect.width() );
    sure you may need some margins.



  • @JoeCFD said in Lost on resizing QListWidget :(:

    QFont font = w->font(); /*get default font */
    QRectF fontBoundRect = QFontMetrics( font ).tightBoundingRect( the longst string );
    w->setFixedWidth( fontBoundRect.width() );

    That works in the same way as my bruit force method, although I prefer to use:
    auto column_width = w.sizeHintForColumn(0); as there is only one column.

    For a simple list widget I would expect to see some 'fitToContents' behaviour.
    Perhaps it is hidden somewhere, but I haven't uncovered it yet.

    (Manually adjusting the size by calculating the contents/margins/frame every time I add/remove an item seems complicated for something that simple).



  • @idlefrog Some basic operation. Better to know it. This applies for more scenarios. Often, some features do not exist while they are expected from Qt.



  • This is my final solution for anyone else out there wondering why their list will not 'fit to content':

    #include <QApplication>
    #include <QListWidget>
    #include <QDebug>
    #include "listwidget.h"
    
    class ListWidget : public QListWidget
    {
    public:
        explicit ListWidget(QWidget *parent = nullptr):QListWidget(parent){}
        ~ListWidget(){}
    
        QSize sizeHint() const
        {
            QSize size = QListWidget::sizeHint();
            auto column_width = sizeHintForColumn(0);
            auto frame_width = frameWidth();
            auto margins = contentsMargins();
            auto new_width = column_width+frame_width + margins.left()+margins.right();
            size.setWidth(new_width);
    
            return size;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        ListWidget w;
        QStringList items = {"C2H6O - Ethanol",
                             "CHCl - Trichloromethane",
                             "CO2 - Carbon Dioxide",
                             "H2O - Water",
                             "NaCl - Sodium Choride",
                             "NH3 - Ammonia"  };
        w.addItems(items);
        w.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
        w.show();
        return a.exec();
    }
    

    Which looks like this:
    6182b3f5-70e8-4d71-9bbf-3c9b760e4094-image.png



  • @JoeCFD Thanks!... It's surprising really. Perhaps Widgets are not being developed now.



  • @idlefrog
    Your solution uses sizeHintForColumn() and overrides sizeHint(). I believe this is indeed the correct approach, as per the accepted solution at QListWidget adjust size to content. However a couple of comments there claim not working at Qt 5.x, so good if it works for you.



  • @JonB Yes, it works fine for me on Qt 5.15.2. Thanks for the support!
    And thanks for the link! (I had found that one too!). :)


Log in to reply