Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Solved Does QMenuBar::clear() release memory of the action created with ?

    General and Desktop
    4
    17
    2663
    Loading More Posts
    • 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.
    • SGaist
      SGaist Lifetime Qt Champion last edited by

      Use a QPointer

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

      T 1 Reply Last reply Reply Quote 1
      • T
        thelfer @SGaist last edited by

        @SGaist Thanks for the tip ! I totally forgot about QPointer. I'll do this tomorrow.

        T 1 Reply Last reply Reply Quote 0
        • T
          thelfer @thelfer last edited by

          Well, using QPointer shows that this->bm is not released by QMenuBar::clear(). Shall we consider

          • that this is normal and one shall release each items (QMenu and QActions) by hand (though I did not think about how to do it in pratice)
          • this is a bug in QMenuBar
            What do you think ?
            Regards
          1 Reply Last reply Reply Quote 0
          • Christian Ehrlicher
            Christian Ehrlicher Lifetime Qt Champion last edited by

            QMenu *QMenuBar::addMenu(const QString &title)

            Appends a new QMenu with title to the menu bar. The menu bar takes ownership of the menu. Returns the new menu.

            So when destroying the menu, the submenus will be gone. There is no constraint that those menus are destroyed on clear() esp. since the the documenation does not state anything releated to this:

            Removes all the actions from the menu bar.

            Qt has to stay free or it will die.

            1 Reply Last reply Reply Quote 0
            • T
              thelfer last edited by

              @Christian-Ehrlicher Since the QMenuBar takes the ownership of the sub-menus, I do not feel that deleting them by hand is legal.

              So, if clear is not meant to release the memory, how to do it ?

              Even the documentation of the removeAction method does not state that the action is deleted. And there is no removeMenu method that would work on submenus.

              Any advice is welcomed.

              mrjj 1 Reply Last reply Reply Quote 0
              • mrjj
                mrjj Lifetime Qt Champion @thelfer last edited by mrjj

                @thelfer
                Hi
                Since Actions can be shared between toolbar and menubar, its reasonable that clear() does not
                free them.
                Its a bit unusual use case but you could do like.

                
                void enumerateMenu(QMenu* menu) {
                  foreach (QAction* action, menu->actions()) {
                    if (action->isSeparator()) {
                      qDebug("this action is a separator");
                    } else if (action->menu()) {
                      qDebug("action: %s", qUtf8Printable(action->text()));
                      qDebug(">>> this action is associated with a submenu, iterating it recursively...");
                      enumerateMenu(action->menu());
                      delete action->menu(); // KILL IT
                      qDebug("<<< finished iterating the submenu");
                    } else {
                      qDebug("action: %s", qUtf8Printable(action->text()));
                      delete action; // KILL IT
                    }
                  }
                }
                
                void MainWindow::on_btRemove_released() {
                  enumerateMenu(bm);
                  delete bm; // bm is member
                }
                

                Seems to clean up as demostrated in this sample where i subclass Aaction to write to qDebug in dtor.
                https://www.dropbox.com/s/jwlpvpva2mx6cy9/FreeMe.zip?dl=0

                I also instrumented QIcon but is assigned by copy so that was not informative.

                enumerateMenu code credits to
                https://stackoverflow.com/questions/9399840/how-to-iterate-through-a-menus-actions-in-qt

                1 Reply Last reply Reply Quote 2
                • Christian Ehrlicher
                  Christian Ehrlicher Lifetime Qt Champion last edited by

                  @thelfer said in Does QMenuBar::clear() release memory of the action created with ?:

                  So, if clear is not meant to release the memory, how to do it ?

                  It's clearly documented:

                  The menu bar takes ownership of the menu.

                  --> When the QMenuBar is destroyed, the QActions will be deleted too.

                  Qt has to stay free or it will die.

                  1 Reply Last reply Reply Quote 2
                  • mrjj
                    mrjj Lifetime Qt Champion last edited by

                    Hi
                    Fooling around with it, maybe just total nuke works best

                    void MainWindow::on_btDelete_released() {
                    delete ui->menuBar;
                    this->setMenuBar( new QMenuBar(this) );
                    }

                    it dont even flashes and clearly delete all.

                    1 Reply Last reply Reply Quote 0
                    • T
                      thelfer last edited by

                      Well, I tested @mrjj approach, and it led to a segfault right from the start. I'll investigate.

                      mrjj 1 Reply Last reply Reply Quote 0
                      • mrjj
                        mrjj Lifetime Qt Champion @thelfer last edited by mrjj

                        @thelfer
                        Oh.
                        enumerateMenu crashed ?
                        I tested it with several subitems.

                        Do you have multiple "items" ?

                        alt text

                        Did sample crash for you? or was in first when used in real code?

                        1 Reply Last reply Reply Quote 0
                        • T
                          thelfer last edited by

                          Well, I found the reason of the segfault: I hold one action as a member. This action was deleted by enumateMenu and the code crashes when this action was added again, which is perfectly normal. I think that I have to refactor my code.
                          Thanks to everyone.

                          mrjj 1 Reply Last reply Reply Quote 1
                          • mrjj
                            mrjj Lifetime Qt Champion @thelfer last edited by

                            @thelfer
                            Ok. good found.
                            I assume its a no go to wipe whole menubar and recreate ?
                            You are keeping some when u "refresh" ?
                            delete ui->menuBar;
                            this->setMenuBar( new QMenuBar(this) );

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post