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

C++ Qt: Best way to make dynamic toolbar contributions



  • Hello,
    I have MainWindow with a toolbar. Within the MainWindow, I have a StackedWidget.
    Inside each page of the StackedWidget, I display another Widget.
    When each page is activated, I want to dynamically add toolbar buttons.
    When a page is deactivated, I want to hide the related toolbar buttons.
    The toolbar buttons will be displayed in the MainWindow, but the actions need to be in the written/invoked in the page widgets.

    What is the best code structure to accomplish this?

    Thanks,
    JG


  • Lifetime Qt Champion

    Hi
    It depends on how many QToolButtons each page will have (to show) and
    if you want to replace all of the toolbar or just a section of it.

    One way to have a fix part and and dynamic part is to use a stackwidget in the toolbar

    alt text

    QWidget *makePage(int buttons)
    {
        QWidget *page = new QWidget;
        QHBoxLayout *horizontalLayout = new QHBoxLayout(page);
        horizontalLayout->setSpacing(2);
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        for (int cc = 0; cc < buttons; ++cc) {
            auto toolButton = new QToolButton(page);
            toolButton->setText(QString::number(cc));
            horizontalLayout->addWidget(toolButton);
        }
        auto horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
        horizontalLayout->addItem(horizontalSpacer);
        return page;
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        stacked = new QStackedWidget;
        stacked->setGeometry(QRect(0, 0, 300, 32));
    
        stacked->addWidget(makePage(2));
        stacked->addWidget(makePage(5));
    
        // the fixed one(s)
        auto t1 = new QToolButton;
        t1->setText("fixed");
        ui->mainToolBar->addWidget(t1);
        // the dynamic part
        ui->mainToolBar->addWidget(stacked);
    }
    
    // and simply change when needed. 
    // this could also be on a signal from the page it self, if you dont want main to handle it.
    
    void MainWindow::on_tabWidget_currentChanged(int index)
    {
        if (index == 0) {
            stacked->setCurrentIndex(0);
        }
    
        if (index == 1) {
            stacked->setCurrentIndex(1);
        }
    }
    
    

    If you want the actual "Pages" to define its toolbar it self,
    You can make a function in your pages that main window
    can call to get its toolbar button page
    and then in mainwin loop over your pages
    at startup and insert the toolbar button pages (so they are ready) and
    give back the index so your page knows what to ask for via a custom signal that
    makes it flip the toolbar stacked to an given index.



  • @mrjj - Nice answer.


Log in to reply