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. [Solved] Keeping a menubar for repeated use in QMainWindow::setMenuBar
Qt 6.11 is out! See what's new in the release blog

[Solved] Keeping a menubar for repeated use in QMainWindow::setMenuBar

Scheduled Pinned Locked Moved Solved General and Desktop
setmenubarqmainwindow
22 Posts 4 Posters 14.2k 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.
  • Chris KawaC Chris Kawa

    @raven-worx Setting a null parent "detaches" the bar from main window. It won't be deleted by the consecutive setMenuBar(). I'm not guessing. I've checked ;)

    H Offline
    H Offline
    Harry123
    wrote on last edited by
    #12

    @Chris-Kawa
    That's a very simple solution to the problem.
    Thank you, I'll be trying it out very soon.

    1 Reply Last reply
    0
    • raven-worxR raven-worx

      @Chris-Kawa
      i see. Because it's contained in a layout.
      Sry for that.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #13

      @raven-worx, @chris-kawa
      http://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qmainwindow.cpp?h=5.5#n517
      I'm sorry to argue, but look up here. Line 535 explicitly deletes the menu!

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #14

        @kshegunov That's true, but note that deletion happens in if (topLayout->menuBar() .... block.
        When you set parent of the bar to nullptr it is taken out of the layout. But don't take my word for it, check:

        qDebug() << mainWindow->layout()->menuBar();  //prints out some pointer
        mainWindow->menuBar()->setParent(nullptr);
        qDebug() << mainWindow->layout()->menuBar();  //prints 0, the bar was taken out
        
        kshegunovK 1 Reply Last reply
        0
        • Chris KawaC Chris Kawa

          @kshegunov That's true, but note that deletion happens in if (topLayout->menuBar() .... block.
          When you set parent of the bar to nullptr it is taken out of the layout. But don't take my word for it, check:

          qDebug() << mainWindow->layout()->menuBar();  //prints out some pointer
          mainWindow->menuBar()->setParent(nullptr);
          qDebug() << mainWindow->layout()->menuBar();  //prints 0, the bar was taken out
          
          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #15

          @Chris-Kawa
          Ah! Yes, you're correct of course. This was my initial idea (reparenting the menu bar) but I discarded it because I didn't realize that the menu will be taken out of the layout, silly me! :)

          Kind regards.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • H Offline
            H Offline
            Harry123
            wrote on last edited by
            #16

            Solution verified as simple and perfectly working.

            What I did was to override QMainWindow::setMenuBar as follows :

            void myMainWindow::setMenuBar(QMenuBar * bar)
            {
              if (menuBar())
                menuBar()->setParent(0);      // detach current menubar so it won't get deleted
              QMainWindow::setMenuBar(bar);
            }
            
            raven-worxR 1 Reply Last reply
            0
            • H Harry123

              Solution verified as simple and perfectly working.

              What I did was to override QMainWindow::setMenuBar as follows :

              void myMainWindow::setMenuBar(QMenuBar * bar)
              {
                if (menuBar())
                  menuBar()->setParent(0);      // detach current menubar so it won't get deleted
                QMainWindow::setMenuBar(bar);
              }
              
              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #17

              @Harry123
              please be advised that this only works as long as the instance is of the type myMainWindow, since setMenuBar() is not virtual.

              Meaning the following wont work, even the object behind the pointer has the correct type:

              QMainWindow* mw = new myMainWindow;  // pointer-type is different from instance-type!
              mw->setMenuBar(...);
              

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              H 1 Reply Last reply
              1
              • raven-worxR raven-worx

                @Harry123
                please be advised that this only works as long as the instance is of the type myMainWindow, since setMenuBar() is not virtual.

                Meaning the following wont work, even the object behind the pointer has the correct type:

                QMainWindow* mw = new myMainWindow;  // pointer-type is different from instance-type!
                mw->setMenuBar(...);
                
                H Offline
                H Offline
                Harry123
                wrote on last edited by
                #18

                @raven-worx

                I have "mw = this;" in the constructor for myMainWindow, where mw is a global variable, and I can now successfully do "mw->setMenuBar(..)" from several other classes with no problem.

                It currently does work - why shouldn't it ?

                1 Reply Last reply
                0
                • Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by Chris Kawa
                  #19

                  @Harry123 It might work for your case but is very dangerous in general. As @raven-worx mentioned setMenuBar() is not virtual. This means that if anyone calls it through a pointer to base class the base class version will be called (which deletes the bar).
                  In general you can't guarantee that your class will only by accessed via pointer to derived class and in fact you should never assume that.
                  Example:

                  QMainWindow* gotcha = mw;
                  mw->setMenuBar(someBar); //ok
                  gotcha->setMenuBar(someOtherBar); //someBar is deleted!
                  

                  Long story short - don't override non-virtual methods. Create a new one with descriptive name.

                  H 1 Reply Last reply
                  1
                  • Chris KawaC Chris Kawa

                    @Harry123 It might work for your case but is very dangerous in general. As @raven-worx mentioned setMenuBar() is not virtual. This means that if anyone calls it through a pointer to base class the base class version will be called (which deletes the bar).
                    In general you can't guarantee that your class will only by accessed via pointer to derived class and in fact you should never assume that.
                    Example:

                    QMainWindow* gotcha = mw;
                    mw->setMenuBar(someBar); //ok
                    gotcha->setMenuBar(someOtherBar); //someBar is deleted!
                    

                    Long story short - don't override non-virtual methods. Create a new one with descriptive name.

                    H Offline
                    H Offline
                    Harry123
                    wrote on last edited by
                    #20

                    @Chris-Kawa
                    I don't have this gotcha - my variable is of type myMainWindow*.
                    This can only not work if there is a bug in the C++ compiler.
                    But perhaps I will rename it, just in case.

                    1 Reply Last reply
                    0
                    • Chris KawaC Offline
                      Chris KawaC Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by
                      #21

                      @Harry123 said:

                      This can only not work if there is a bug in the C++ compiler.

                      As I said - it works here and now for you. But who's to say in a month or a year another person will for whatever reason create a local variable of type QMainWindow* and copy your pointer. The point is that because this method is not virtual a different method will be called depending on the type of pointer you access it through. That's a time bomb type of bug. It does not explode here and now for you but it will for someone else or future you.

                      H 1 Reply Last reply
                      0
                      • Chris KawaC Chris Kawa

                        @Harry123 said:

                        This can only not work if there is a bug in the C++ compiler.

                        As I said - it works here and now for you. But who's to say in a month or a year another person will for whatever reason create a local variable of type QMainWindow* and copy your pointer. The point is that because this method is not virtual a different method will be called depending on the type of pointer you access it through. That's a time bomb type of bug. It does not explode here and now for you but it will for someone else or future you.

                        H Offline
                        H Offline
                        Harry123
                        wrote on last edited by
                        #22

                        @Chris-Kawa
                        Totally agree.

                        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