Automatically stretch QTableWidget to fit resized window



  • I have a QBoxLayout in QBoxLayout::TopToBottom alignment mode to which I have added 2 QFrame widgets.

    QBoxLayout layout;
    central_widget.setLayout(&layout);
    ...
    layout.addWidget(&form_frame, 0, Qt::AlignTop);
    layout.addWidget(&btn_frame,  0, Qt::AlignBottom);
    

    I would like the form_frame to stretch to fit both vertically and horizontally when the window is resized, but at the moment it only stretches horizontally.

    Here is an example:

    (full working code below)

    The window as it comes up by default:

    default

    The window after resizing:

    resized

    I would like the QTableWidget (or it's parent QFrame) it stretch vertically too, as marked here:

    stretch vertically

    Code producing example:

    #include <QApplication>
    #include <QMainWindow>
    #include <QFormLayout>
    #include <QPushButton>
    #include <QTableWidget>
    
    class App
    {
    public:
        App(int argc, char** argv)
            : app(argc, argv)
            , layout(QBoxLayout::TopToBottom)
        {
            window.setCentralWidget(&central);
        }
    
        int exec()
        {
            central.setLayout(&layout);
            layout.addWidget(&form_frame, 0, Qt::AlignTop);
            layout.addWidget(&btn_frame,  0, Qt::AlignBottom);
    
            form_frame.setLayout(&form_layout);
            btn_frame.setLayout(&btn_layout);
    
            // create a table widget
            QTableWidget* table = new QTableWidget(0, 2);
            form_layout.addRow(table);
            QStringList labels;
            labels << "header 1" << "header 2";
            table->setHorizontalHeaderLabels(labels);
    
            // create some buttons
            btn_save   = new QPushButton("&save");
            btn_cancel = new QPushButton("&cancel");
            btn_layout.addWidget(btn_save);
            btn_layout.addWidget(btn_cancel);
    
            window.show();
            return app.exec();
        }
    
        QApplication app;
        QMainWindow  window;
    
        QWidget      central;
        QBoxLayout   layout;
    
        QFrame       form_frame;
        QFormLayout  form_layout;
    
        QFrame       btn_frame;
        QHBoxLayout  btn_layout;
        QPushButton* btn_save;
        QPushButton* btn_cancel;
    };
    
    int main(int argc, char** argv)
    {
        return App(argc, argv).exec();
    }
    
    

  • Qt Champions 2016

    Hello,
    Try this layout.setStretch(0, 1);



  • @kshegunov said:

    layout.setStretch(0, 1);

    Thanks for the suggestion, but doesn't look like that works


  • Lifetime Qt Champion

    Hi,

    Here's a more lightweight version of your UI that does what you want:

    int main(int argc, char** argv)
    {
        QApplication app(argc, argv);
        QMainWindow  window;
        QWidget *centralWidget = new QWidget;
        window.setCentralWidget(centralWidget);
        QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget);
    
        QTableWidget* table = new QTableWidget(0, 2);
        QStringList labels;
        labels << "header 1" << "header 2";
        table->setHorizontalHeaderLabels(labels);
    
        QHBoxLayout *btnLayout = new QHBoxLayout;
        btnLayout->addWidget(new QPushButton("&save"));
        btnLayout->addWidget(new QPushButton("&cancel"));
    
        centralLayout->addWidget(table);
        centralLayout->addLayout(btnLayout);
    
        window.show();
        return app.exec();
    }
    

    It uses less widgets and more suitable layouts.


  • Qt Champions 2016

    @skebanga
    Oh, I didn't realize you use a box layout and not a vbox ... silly me.
    Try what @SGaist suggested.
    Also as a note, you can even forgo creating a new central widget:
    QVBoxLayout *centralLayout = new QVBoxLayout(window.centralWidget());
    should do the trick.



  • @kshegunov

    QVBoxLayout *centralLayout = new QVBoxLayout(window.centralWidget());
    

    That doesn't seem to work - it just gives me a blank screen.

    Seems I have to set a central widget on the QMainWindow in order for it to show anything

    QMainWindow  window;
    QWidget      central;
    window.setCentralWidget(&central);
    QVBoxLayout* centralLayout = new QVBoxLayout(&central);

  • Qt Champions 2016

    @skebanga
    It's not my day today. Indeed you do need to create it, I rely on the form editor too much and am losing touch with coded layouts/windows it seems.



  • @SGaist

    Thanks for the suggestion.

    In terms of the layouts and widgets I used in my example, it was a stripped down version of something I have already in my app framework - stripped down to try make a MCVE.

    What I actually have is something like a building block which I use to create custom "settings dialogs" for various different applications.

    I have a central window with a QFormLayout at the top and a QHBoxLayout at the bottom with save and cancel QPushButtons.

    The QFrames have QFrame::Panel frame style to delineate them.

    The QFormLayout at the top is empty, and the various users add rows to it as they see fit.

    It sort of looks like this with nothing on it:

    Empty settings dialog

    When the user wants to add a new row, they call the following function which gives them back a QFormLayout to which they can add whatever widgets they want:

    QFormLayout* SettingsDialog::addFormGroup(const QString& title)
    {
        QFrame* frame = new QFrame;
        frame->setFrameStyle(QFrame::Panel);
        _form_layout.addRow(frame);
    
        QFormLayout* form_group_layout = new QFormLayout;
        frame->setLayout(form_group_layout);
    
        if (!title.isEmpty())
            form_group_layout->addRow(new QLabel(title));
        return form_group_layout;
    }
    
    

    Here is an example of it being used with 2 form group rows in the QFormLayout

    Settings with 2 rows

    Here is me playing with getting the QTableWidget into my settings dialog:

    Settings with QTableWidget

    Here is the same QTableWidget settings dialog when resized, which I am struggling with:

    Settings with QTableWidget not stretched

    Sorry if this is getting a bit verbose. Hopefully I've managed to explain what I'm doing and why I have the weird combination of QFrame and QFormLayout etc?

    Thanks for the assistance!


  • Qt Champions 2016

    @skebanga
    Why not just create a simple VBox layout to insert into your central widget layout and add the frames there? Seems the most simple solution to me.



  • @skebanga
    Not sure but please try this. I was facing similar issue , this solved it.
    SearchTable->horizontalHeader()->setStretchLastSection(true);



  • Thank you @SGaist and @kshegunov

    Between your examples and suggestions I have managed to achieve what I want.



  • @doshirushabh

    SearchTable->horizontalHeader()->setStretchLastSection(true);

    I don't believe this is what I'm looking for here, as this is to stretch the last section of the table as the table is resized, whereas I want to stretch the table itself.


  • Qt Champions 2016

    @skebanga
    Good job! :)



  • @skebanga
    Hello. If you can please tell how did you achieve that . I have similar issues

    Thanks !!!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.