Reputation: 1234
I'm trying to learn Qt and C++ and having some trouble understanding the C++ this keywork. I've seen examples where a class is derived from QMainWindow and then within the class member functions, a QMenu is added. One example is the "Simple menu" program described on this page:
http://www.zetcode.com/gui/qt4/menusandtoolbars/
In that example, a quit action is created with
QAction *quit = new QAction("&Quit", this);
However, imagine I want to also derive a class from QMenu and use that to create my menu.
mymenu.h
class MainWindow; // forward declaration
class MyMenu : QMenuBar
{
public:
MyMenu(MainWindow *main_window);
};
mymenu.cpp
#include "mymenu.hpp"
MyMenu::MyMenu(MainWindow *main_window) : QMenuBar()
{
QAction *quit = new QAction("&Quit", main_window); // Notice here I replaced
// 'this' with 'main_window'
QMenu = *file;
file = menuBar()->addMenu("&File");
file->addAction(quit);
connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
}
Unfortunately this doesn't work because QAction expects a QObject as a parent. All that being said, there are a couple things that don't make sense to me:
I apologize for such a long winded question, but if any of you have made it to the end with me, I would love any suggestions as to what I am missing here. The end goal here is just to create a derived class of QMenu (MyMenu here) and add it to the QMainWindow derived class (MainWindow here) existing in a separate class. Thank you for your time.
Upvotes: 2
Views: 2879
Reputation:
If the class MainWindow inherits from QMainWindow, doesn't that make 'MainWindow' a QObject?
Yes, MainWindow
is a QMainWindow
which is a QObject
(you can see this by browsing the inheritance tree on the API docs).
You have only forward declared MainWindow
. Since the compiler does not have a definition for the class MainWindow
it can only do miminal things with a pointer to MainWindow
. In order for the compiler to "know" that MainWindow
is a QMainWindow
which is a QObject
, you must provide a class definition for MainWindow
. You can solve your compiler error with:
#include "MainWindow.h"
No dynamic cast is needed
Also, in Qt land to make something "really" a QObject you should put the Q_OBJECT macro on the object:
class MyMenu : QMenuBar
{
Q_OBJECT
public:
MyMenu(MainWindow *main_window);
};
It might save you a few headaches later on if you ever plan to use the object for signal/slots or other Qt stuff.
What is the difference between passing 'this' to QAction from within the class MainWindow, as opposed to passing 'main_window' which is (as far as I can tell) also a pointer to the instance from within the MyMenu class?
this
is a pointer to your custom MyMenu
class which is also a QMenuBar
. main_window
is a pointer to your custom MainMenu
class which is also a a QMainMenu
. So, two different objects in memory. The second argument of the QAction
constructor takes a pointer to a parent widget. The parent widget is responsible for managing the memory of its children. Since it takes a QObject
its reasonable to pass in either this
or main_menu
.
Also you should probably pass a parent to the QMenu
constructor.
MyMenu::MyMenu(MainWindow *main_window) : QMenuBar(main_window)
This way MyMenu
is correctly deleted when the MainWindow
is deleted.
The usual Qt paradigm is:
MyMenu::MyMenu(<arg1>, <arg2>, ... QObject * parent) : QMenuBar(parent)
But in this case forwarding along main_window
is good enough.
Upvotes: 1