Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. tabifyDockWidget() adding unknown widgets
Forum Updated to NodeBB v4.3 + New Features

tabifyDockWidget() adding unknown widgets

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 2 Posters 1.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Julieng
    wrote on last edited by
    #3

    Hello SGaist, when I comment the "tabifyDockWidget" line, I do not have any issue.

    Code inside the customWidgets is quite simple.

    An example:

        QWidget * widget = new QWidget();
        setWidget(widget);
        QVBoxLayout * layout = new QVBoxLayout();
        widget->setLayout(layout);
         m_map = new baseItemMap(); // With m_map beeing a QCustomPlot figure
         layout->addWidget(m_map);
    

    Another example:

        QScrollArea * scroll = new QScrollArea();
        setWidget(scroll);
        scroll->setBackgroundRole(QPalette::Light);
        scroll->setFrameShape(QFrame::NoFrame);
        scroll->setWidgetResizable(true);
        QWidget * widget = new QWidget();
        scroll->setWidget(widget);
        QVBoxLayout * layout = new QVBoxLayout();
        widget->setLayout(layout);
    
        QLabel * labTX = new QLabel(tr("<b>Text</b>"));
        layout->addWidget(labTX);
    
        m_table = new customTableView(); // Derived from a QTableView
        layout->addWidget(m_table);
    
    1 Reply Last reply
    0
    • J Offline
      J Offline
      Julieng
      wrote on last edited by
      #4

      I've just tried with empty customWidget and I continue to "leak" widgets.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #5

        I just realized, when you call tabify, there's a QTabWidget that is created and tabs added for each widget you put together.

        There you have the three widgets.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • J Offline
          J Offline
          Julieng
          wrote on last edited by
          #6

          Thanks SGaist, that's an interesting point ! So, how could I remove these QTabWidgets ? Do I have to do it before or after the following piece of code ?

           for(uncloseableDockWidget * w:m_widgets) {
                m_container->removeDockWidget(w);
                delete w;
          }
          m_widgets.clear();
          
          1 Reply Last reply
          0
          • J Offline
            J Offline
            Julieng
            wrote on last edited by
            #7

            I tried to remove the central widget like this :

            delete m_container->centralWidget();
            

            and build a new one. I thought that these additional widgets would be "parented" to the central widget. However, it does not work. Any idea to delete it ?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #8

              Well, I think you have found an edge case. From the quick look I did to the sources of QMainWindow and its internal classes, the fact that you are deleting the dock widget every time seems to not be handled in the "tabification" part (I have to take a deeper dive to ensure that).

              I must say that it's pretty unusual to completely destroy dock widgets and recreate them like you are currently doing.

              Would you mind providing a minimal compilable example to reproduce that ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              2
              • J Offline
                J Offline
                Julieng
                wrote on last edited by
                #9

                Thanks SGaist, here is a complete exemple :

                main.cpp:

                #include "mainwindow.h"
                #include <QApplication>
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    MainWindow w;
                    w.show();
                
                    return a.exec();
                }
                

                mainwindow.h

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <iostream>
                #include <QMainWindow>
                #include <QDockWidget>
                #include <QCloseEvent>
                #include <QLabel>
                #include <QPushButton>
                #include <QBoxLayout>
                #include <QApplication>
                
                class uncloseableDockWidget : public QDockWidget {
                    Q_OBJECT
                
                public:
                    /**
                     * @brief Constructor
                     * @param title: title
                     * @param parent: parent widget
                     * @param flags: flags
                     */
                    explicit uncloseableDockWidget(const QString & title, QWidget * parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()) : QDockWidget(title, parent, flags) {
                        setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
                        setAllowedAreas(Qt::AllDockWidgetAreas);
                    }
                
                    /**
                     * @brief Destructor
                     */
                    virtual ~uncloseableDockWidget() override {}
                
                public slots:
                    /**
                     * @brief Update view
                     */
                    virtual void updateView() = 0;
                
                protected:
                    /**
                     * @brief Close event
                     * @param event: event
                     */
                    void closeEvent(QCloseEvent * event) override {
                        event->ignore();
                    }
                };
                
                class dock : public uncloseableDockWidget {
                    Q_OBJECT
                
                public:
                    dock(const QString & title, QWidget * parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()) : uncloseableDockWidget(title, parent, flags) {}
                
                    void updateView() override {}
                };
                
                class tab1 : public QWidget {
                    Q_OBJECT
                
                public:
                    tab1(QWidget * parent = nullptr) : QWidget(parent) {
                        QVBoxLayout * layout = new QVBoxLayout();
                        setLayout(layout);
                        QPushButton * bt = new QPushButton("test");
                        layout->addWidget(bt);
                        connect(bt, SIGNAL(clicked()), this, SIGNAL(btClicked()));
                    }
                
                signals:
                    void btClicked();
                };
                
                class tab2 : public QWidget {
                    Q_OBJECT
                
                public:
                    tab2(QWidget * parent = nullptr) : QWidget(parent) {
                        QVBoxLayout * layout = new QVBoxLayout();
                        setLayout(layout);
                        m_content = new QMainWindow();
                        layout->addWidget(m_content);
                        m_content->setCentralWidget(new QLabel("test"));
                    }
                
                public slots:
                    void update() {
                        std::cout << "test1: " << QApplication::allWidgets().size() << std::endl;
                        // Remove already existing dock widgets
                        for(uncloseableDockWidget * w:m_docks) {
                            m_content->removeDockWidget(w);
                            delete w;
                        }
                        m_docks.clear();
                        std::cout << "test2: " << QApplication::allWidgets().size() << std::endl;
                        // Add new dock widgets
                        m_docks.emplace_back(new dock("title1"));
                        m_docks.emplace_back(new dock("title2"));
                        m_docks.emplace_back(new dock("title3"));
                        std::cout << "test3: " << QApplication::allWidgets().size() << std::endl;
                        // Add and tabify dock widgets
                        for(uncloseableDockWidget * w:m_docks)
                            m_content->addDockWidget(Qt::RightDockWidgetArea, w);
                        std::cout << "test4: " << QApplication::allWidgets().size() << std::endl;
                        for(unsigned int i=1; i<m_docks.size(); i++)
                            m_content->tabifyDockWidget(m_docks[i-1], m_docks[i]);
                        std::cout << "test5: " << QApplication::allWidgets().size() << std::endl;
                        if(m_docks.size())
                            m_docks.front()->raise();
                        std::cout << "test6: " << QApplication::allWidgets().size() << std::endl;
                    }
                
                private:
                    QMainWindow * m_content = nullptr;
                    std::vector<uncloseableDockWidget *> m_docks;
                };
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    MainWindow(QWidget * /*parent*/ = nullptr) {
                        m_tab = new QTabWidget();
                        setCentralWidget(m_tab);
                        tab1 * t1 = new tab1();
                        m_tab->addTab(t1, "t1");
                        tab2 * t2 = new tab2();
                        m_tab->addTab(t2, "t2");
                        connect(t1, SIGNAL(btClicked()), t2, SLOT(update()));
                    }
                
                    ~MainWindow() {
                
                    }
                private:
                    QTabWidget * m_tab = nullptr;
                };
                
                #endif // MAINWINDOW_H
                

                Clicking various times on the "test" button in tab 1, you can see that number of widgets increases.

                1 Reply Last reply
                1
                • J Offline
                  J Offline
                  Julieng
                  wrote on last edited by
                  #10

                  Hello SGaist, is the example I provided enough to understand my issue ? Do you think I could get a workaround in order to avoid "leaking" widgets ? Thnanks in advance.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #11

                    So it looks like I never submitted my answer, sorry !

                    I took a look at the internals of QMainWindow and the handling of the QDockWidget "tabification" is more involved than what I thought.

                    There's no easy workaround per se but there's something I though about: do you really need to delete these dock widgets all the time ? Would a reset of their content be enough ? If you really need to delete them, what about just replacing the widget they contain ? Doing so, you would only have a set of QDockWidget and thus avoid the issue you are currently having.

                    In any case, I think it would be worth checking the bug report system to see if there's something related and if not, please open a repot providing your small code sample (including the corresponding pro file).

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      Julieng
                      wrote on last edited by
                      #12

                      Thanks SGaist for you answers ! I can change the way I manage the dock widgets (I could just clear the QMainWindow which contains these docks even if I think it will not be as elegant as my first solution). I'll open a bug report as you propose.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        I was rather thinking about cleaning the widgets within the dock widgets. So you keep the number of QDockWidgets constant.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved