Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Qt, how do I use Q_OBJECT slots and signals with multiple inheritance?

Tags:

qt

qobject

I looked through the related questions and couldn't find anything that addresses exactly what I was talking about, so let me describe.

I have a class, let's say foo that needs to have its own slots and signals, but also needs to inherit from QXmlDefaultHandler (sounds rather odd, but I encountered this situation when trying to use QHttp to read a website directly into a QBuffer).

class foo: public QXmlDefaultHandler, public QObject
{
    public:
        foo();
        ~foo();

       Q_OBJECT
   public slots:
       void bar();
}

This code, if accompanied by a cpp to connect bar to a signal somewhere else, will not compile. You'll get errors about some members of QObject not being a member of QXmlDefaultHandler. Additionally, you can't move Q_OBJECT or else you get vtable errors for not implementing some things (go on! try it!).

please see my answer for the (very simple) fix. I will entertain voting you as the accepted answer if I think you explain it better than I do.

edit: for you c++ and Qt vets, please post an answer if you can explain it better. i spent quite a bit of time looking this info up, so please help someone else if you can do better than me.

like image 758
San Jacinto Avatar asked Sep 28 '09 20:09

San Jacinto


2 Answers

The documentation for moc states that in cases of multiple inheritance, the class providing QObject should appear first

If you are using multiple inheritance, moc assumes that the first inherited class is a subclass of QObject. Also, be sure that only the first inherited class is a QObject.

 // correct
 class SomeClass : public QObject, public OtherClass
 {
     ...
 };

Virtual inheritance with QObject is not supported.

like image 142
Paul Dixon Avatar answered Sep 19 '22 22:09

Paul Dixon


class foo: public QObject, public QXmlDefaultHandler
{
    public:
        foo();
        ~foo();
   Q_OBJECT
   public slots:
       void bar();
}

As simple as it sounds, if you don't put QObject first in the inheritance list, this task is impossible. It's a limitation in Qt's meta object system. If you don't do this, the compiler will try to apply some members of QObject as part of QXmlDefaultHandler.

like image 28
San Jacinto Avatar answered Sep 17 '22 22:09

San Jacinto