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 31 Dec 2019, 06:57 last edited by
    #4

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

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 31 Dec 2019, 07:32 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 31 Dec 2019, 14:18 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 1 Jan 2020, 17:12 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
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 1 Jan 2020, 19:48 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 2 Jan 2020, 10:58 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 10 Jan 2020, 19:29 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
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 11 Jan 2020, 16:35 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 12 Jan 2020, 20:06 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
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 12 Jan 2020, 20:19 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