hobenkr
hobenkr

Reputation: 1234

C++ Qt Derived Classes

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:

  1. If the class MainWindow inherits from QMainWindow, doesn't that make 'MainWindow' a QObject?
  2. 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?

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

Answers (1)

user2836797
user2836797

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

Related Questions