Search code examples
c++qtqwidgetqmainwindowqlayout

Derive QMainWindow and change its layout


I have a big problem with customizing QMainWindow because I don't know how to achieve the following thing:

In the QMainWindow documentation the QMainWindow is presented to have some special areas for toolbars, dock widgets, status bars, and other:

enter image description here

Now what I would want is have a new and custom area for a new custom type of widget, for example:

enter image description here

I tried deriving QWidget and putting my Custom Widget up, and underneath it a QMainWindow but using this method I have to redirect all the standard QMainWindow methods from my QWidget to its QMainWindow child which is very inconvenient.

My question is: Is it possible to customize the QMainWindow layout and add an additional area to the standard layout like the Custom Widget Area in the picture above?


Solution

  • I've got two news for you: bad and good.

    Bad news: QMainWindow uses QMainWindowLayout that is a part of Qt private headers so you can`t customize layout 'honestly', as-is.

    But you can still do it. There is a QMainWindow::setMenuWidget method that can be useful for you. If your main window does not have menu bar then you can simply write

    setMenuWidget(myCustomWidget);
    

    and myCustomWidget will be placed at the top of the window.

    However it is not that easy if you have menu bar in your app. But even in that case you may still place at the top of the window a widget that consists of two parts: your custom widget above and menu bar below. For example for QtDesigner-generated window that can be done like below:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        QLabel *coolLabel = new QLabel("The coolest text in the world", this);
        QWidget *menuWidget = new QWidget;
        QVBoxLayout *vLayout = new QVBoxLayout;
        menuWidget->setLayout(vLayout);
        vLayout->addWidget(coolLabel);
        vLayout->addWidget(ui->menuBar);
        setMenuWidget(menuWidget);
    }