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. why QWidget inherited class can't handle QAction ?
Forum Updated to NodeBB v4.3 + New Features

why QWidget inherited class can't handle QAction ?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 749 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.
  • L Offline
    L Offline
    Loic B.
    wrote on last edited by
    #1

    Hello,

    While developping a small application, i faced a weird behavior concerning QAction. Why a QWidget inherited class cannot handle a QAction ? I made a small example to illustrate my problem:

    a.h

    #include <QObject>
    #include <QWidget>
    #include <QMainWindow>
    #include <QMenuBar>
    #include <QMenu>
    #include <QAction>
    
    using BaseClass = QObject;
    
    class A : public BaseClass
    {
    	Q_OBJECT
    
    public:
    
    	A(QMainWindow& mw) : BaseClass(&mw), m_menu("A"), m_action("a")
    	{
    		m_menu.addAction(&m_action);
    
    		mw.menuBar()->addMenu(&m_menu);
    	}
    
    private:
    
    	QMenu m_menu;
    	QAction m_action;
    
    };
    

    main.cpp

    #include <QApplication>
    #include <QMainWindow>
    #include <QMenuBar>
    #include <QMenu>
    #include <QAction>
    
    #include "a.h"
    
    int main(int argc, char* argv[])
    {
    	QApplication app(argc, argv);
    
    	QMainWindow mw;
    
    	QAction quitAction("Quit");
    	QMenu fileMenu("File");
    	fileMenu.addAction(&quitAction);
    	mw.menuBar()->addMenu(&fileMenu);
    
    	A a(mw);
    
    	mw.show();
    
    	return app.exec();
    }
    

    In the a.h file, when I replace QObject by QWidget for the using BaseClass, the menuBar is not working anymore, I cannot click on any menus. Why ? 0_o

    I searched in the documentation but i did not find any information...

    Thanks in advance !

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

      Hi,

      That's a good question however I can't answer right away.

      That said, your code as it is does not really follow best practices in terms of handling QObject based classes so I am wondering if there's some bad interaction there.

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

      L 1 Reply Last reply
      0
      • Chris KawaC Online
        Chris KawaC Online
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #3

        It's because of this part:

        BaseClass(&mw),
        

        Setting a parent on a widget adds that widget to the parent, so you just added A widget to your main window. Because it's not in any layout it sits in the top left corner, covering the menus (that's why you can't click any). It's transparent though so you can't see it.
        Add a paint event like this to your A class to see what I mean:

        void paintEvent(QPaintEvent*)
        {
            QPainter p(this);
            p.fillRect(rect(), Qt::red);
        }
        
        SGaistS L 2 Replies Last reply
        5
        • Chris KawaC Chris Kawa

          It's because of this part:

          BaseClass(&mw),
          

          Setting a parent on a widget adds that widget to the parent, so you just added A widget to your main window. Because it's not in any layout it sits in the top left corner, covering the menus (that's why you can't click any). It's transparent though so you can't see it.
          Add a paint event like this to your A class to see what I mean:

          void paintEvent(QPaintEvent*)
          {
              QPainter p(this);
              p.fillRect(rect(), Qt::red);
          }
          
          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Chris-Kawa good catch ! I went for "non-clickable" rather than "hidden by".

          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
          1
          • SGaistS SGaist

            Hi,

            That's a good question however I can't answer right away.

            That said, your code as it is does not really follow best practices in terms of handling QObject based classes so I am wondering if there's some bad interaction there.

            L Offline
            L Offline
            Loic B.
            wrote on last edited by
            #5

            @SGaist Thanks for the reply ! Concerning the best practices for handling QObject, do you have any ressources regrouping informations ? Or I can find them along the Qt documentation.

            I use Qt also in my company and I make projects alongside in my personal time to improve my skills. I find Qt hard to handle if you don't want to use raw pointers to follow c++ core guideline or something similar for example. I will be grateful if you could link me some materials :)

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

              You have a truck load of examples in Qt's documentation.
              That said it looks like you are trying to work against Qt's parent/child and QObject design by making everything stack based. Trying to keep absolutely everything on the stack will have issues like double deletion happening with properly parented objects. Making everything allocated on the heap is wrong as well. You should learn when to use which so your tool belt will be more complete.

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

              L 1 Reply Last reply
              1
              • Chris KawaC Chris Kawa

                It's because of this part:

                BaseClass(&mw),
                

                Setting a parent on a widget adds that widget to the parent, so you just added A widget to your main window. Because it's not in any layout it sits in the top left corner, covering the menus (that's why you can't click any). It's transparent though so you can't see it.
                Add a paint event like this to your A class to see what I mean:

                void paintEvent(QPaintEvent*)
                {
                    QPainter p(this);
                    p.fillRect(rect(), Qt::red);
                }
                
                L Offline
                L Offline
                Loic B.
                wrote on last edited by Loic B.
                #7

                @Chris-Kawa Thanks ! It makes sense now ^^

                In my application, I decided to use a MVC like approach with a Gui class inheriting QWidget (so I can make it dockable) to handle and the UI generated by QtDesigner (or manually made) and elements like actions to put in menuBar of the main window. I think it is now compromised...

                Do you have any idea of how to handle that ?

                Edit: Well no I can do it anyway, I just need to hide the widget and it works...

                1 Reply Last reply
                0
                • SGaistS SGaist

                  You have a truck load of examples in Qt's documentation.
                  That said it looks like you are trying to work against Qt's parent/child and QObject design by making everything stack based. Trying to keep absolutely everything on the stack will have issues like double deletion happening with properly parented objects. Making everything allocated on the heap is wrong as well. You should learn when to use which so your tool belt will be more complete.

                  L Offline
                  L Offline
                  Loic B.
                  wrote on last edited by
                  #8

                  @SGaist Yes, I find ugly and so outdated the use of raw pointers. I think I have to back off and keep it to myself ^^.
                  Fingers crossed for a better approach in Qt6...

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

                    You can uncross them. Raw pointers are not going anywhere.

                    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