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

Resize QListWidget in scroll area



  • I would like to create a scroll area with 2 QListWidget objects, side-by-side:

    • the first one, with text

    • the second one, with the line number

    Since the line number should be aligned with the corresponding line, both QListWidget objects are inserted in a QSrollArea widget.
    I want that when lines are added in the QListWidget objects, the height of these widgets are updated so that no scroll bar appears in them, and on the contrary, a scroll bar appears in the QScrollArea widget.

    I have tried different solutions, but without success. I have created a simple project which shows the problem.
    The mainWindow files are:
    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QListWidget>
    #include <QScrollArea>
    #include <QHBoxLayout>
    #include <QWidget>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        QScrollArea *scrollArea;
        QListWidget *listWidgetMain;
        QListWidget *listWidgetLineNumbers;
        QHBoxLayout *horizLayoutMain;
        QHBoxLayout *horizLayoutInScrollArea;
        QWidget *widgetInScrollArea;
        QWidget *centralWidget;
    };
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp:

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        int numLine;
    
        // QListWidget objects
        listWidgetMain = new QListWidget();
        listWidgetLineNumbers = new QListWidget();
        for (numLine = 0; numLine < 20; numLine++)
        {
            listWidgetMain->addItem("text_" + QString::number(numLine + 1));
            listWidgetLineNumbers->addItem(QString::number(numLine + 1));
        }
    
        // Layout with the lists built
        horizLayoutInScrollArea = new QHBoxLayout();
        horizLayoutInScrollArea->addWidget(listWidgetMain);
        horizLayoutInScrollArea->addWidget(listWidgetLineNumbers);
    
        // Scroll area
        widgetInScrollArea = new QWidget();
        widgetInScrollArea->setLayout(horizLayoutInScrollArea);
        scrollArea = new QScrollArea();
        scrollArea->setWidget(widgetInScrollArea);
        scrollArea->setWidgetResizable(true);
    
        // Main layout
        horizLayoutMain = new QHBoxLayout();
        horizLayoutMain->addWidget(scrollArea);
    
        // Main widget
        centralWidget = new QWidget();
        setCentralWidget(centralWidget);
        centralWidget->setLayout(horizLayoutMain);
    }
    

    I have missed probably the right option which does it automatically, so if anyone has an idea, it would be great!
    Thanks in advance for your help!
    Laurent



  • I have finally found a solution, which consists in setting the minimum height of the "QListWidget", equal to: (number or rows + 1) * height of row
    The final code of the example is (only the last lines have been added):

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        int numLine, lineHeight;
        QRect rectItem;
    
        // QListWidget objects
        listWidgetMain = new QListWidget();
        listWidgetLineNumbers = new QListWidget();
        for (numLine = 0; numLine < 20; numLine++)
        {
            listWidgetMain->addItem("text_" + QString::number(numLine + 1));
            listWidgetLineNumbers->addItem(QString::number(numLine + 1));
        }
    
        // Layout with the lists built
        horizLayoutInScrollArea = new QHBoxLayout();
        horizLayoutInScrollArea->addWidget(listWidgetMain);
        horizLayoutInScrollArea->addWidget(listWidgetLineNumbers);
    
        // Scroll area
        widgetInScrollArea = new QWidget();
        widgetInScrollArea->setLayout(horizLayoutInScrollArea);
        scrollArea = new QScrollArea();
        scrollArea->setWidget(widgetInScrollArea);
        scrollArea->setWidgetResizable(true);
    
        // Main layout
        horizLayoutMain = new QHBoxLayout();
        horizLayoutMain->addWidget(scrollArea);
    
        // Main widget
        centralWidget = new QWidget();
        setCentralWidget(centralWidget);
        centralWidget->setLayout(horizLayoutMain);
    
        // Setting of the minimum height
        QListWidgetItem *firstLine;
        firstLine = listWidgetMain->item(0);
        rectItem = listWidgetMain->visualItemRect(firstLine);
        lineHeight = rectItem.height();
        listWidgetMain->setMinimumHeight(lineHeight * (listWidgetMain->count() + 1));
    }
    


  • @Combas
    Totally untested, just intuitive: your want your two QListWidgets to have the CanGrow flag, so they expand to their content, while the QScrollArea stays at some fixed height, so it accommodates the list widgets with scroll on itself. I too have to fiddle around to get this sort of thing right :)



  • Why not just using a QTreeWidget with 2 columns?



  • @JonB Thank you for your reply. You have pefectly understood what I want to do.

    I tried before the method "setSizePolicy" but have not found the right option which fits my need (I tried "QSizePolicy::Expanding", "QSizePolicy::MinimumExpanding" and "QSizePolicy::Ignored" but none of them do what I want)



  • @Combas
    I know, I have to play with the various values too, it doesn't seem to be obvious! :(

    But @Bonnie's suggestion looks interesting: is it convenient for you to have one QListWidget with a pair of columns, that would be much easier? Or is that not good for your situation?



  • @Bonnie If there is no other solution, it could be a possibility. But I have already a code which works with the text part (which is based on a QListWidget) and just wanted to add the line number information. So, if I can keep my previous code by just adapting the display of QListWidget, it would be easier for me.



  • I have finally found a solution, which consists in setting the minimum height of the "QListWidget", equal to: (number or rows + 1) * height of row
    The final code of the example is (only the last lines have been added):

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        int numLine, lineHeight;
        QRect rectItem;
    
        // QListWidget objects
        listWidgetMain = new QListWidget();
        listWidgetLineNumbers = new QListWidget();
        for (numLine = 0; numLine < 20; numLine++)
        {
            listWidgetMain->addItem("text_" + QString::number(numLine + 1));
            listWidgetLineNumbers->addItem(QString::number(numLine + 1));
        }
    
        // Layout with the lists built
        horizLayoutInScrollArea = new QHBoxLayout();
        horizLayoutInScrollArea->addWidget(listWidgetMain);
        horizLayoutInScrollArea->addWidget(listWidgetLineNumbers);
    
        // Scroll area
        widgetInScrollArea = new QWidget();
        widgetInScrollArea->setLayout(horizLayoutInScrollArea);
        scrollArea = new QScrollArea();
        scrollArea->setWidget(widgetInScrollArea);
        scrollArea->setWidgetResizable(true);
    
        // Main layout
        horizLayoutMain = new QHBoxLayout();
        horizLayoutMain->addWidget(scrollArea);
    
        // Main widget
        centralWidget = new QWidget();
        setCentralWidget(centralWidget);
        centralWidget->setLayout(horizLayoutMain);
    
        // Setting of the minimum height
        QListWidgetItem *firstLine;
        firstLine = listWidgetMain->item(0);
        rectItem = listWidgetMain->visualItemRect(firstLine);
        lineHeight = rectItem.height();
        listWidgetMain->setMinimumHeight(lineHeight * (listWidgetMain->count() + 1));
    }
    

Log in to reply