2009-09-28 3 views
6

Я просмотрел связанные вопросы и не смог найти ничего, что касается именно того, о чем я говорил, поэтому позвольте мне описать.В Qt, как использовать слоты Q_OBJECT и сигналы с множественным наследованием?

У меня есть класс, скажем, foo, который должен иметь свои слоты и сигналы, но также должен унаследовать от QXmlDefaultHandler (звучит довольно странно, но я столкнулся с этой ситуацией при попытке использовать QHttp для чтения веб-сайта непосредственно в a QBuffer).

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

     Q_OBJECT 
    public slots: 
     void bar(); 
} 

Этот код, если он сопровождается cpp для подключения бара к сигналу в другом месте, не будет компилироваться. Вы получите ошибки о том, что некоторые члены QObject не являются членами QXmlDefaultHandler. Кроме того, вы не можете перемещать Q_OBJECT, иначе вы получите ошибки vtable для того, чтобы не реализовывать некоторые вещи (продолжайте! Попробуйте!).

см. Мой ответ для (очень простого) исправления. Я буду принимать участие в голосовании в качестве принятого ответа, если я думаю, что вы объясните это лучше, чем я.

Редактировать: для вас C++ и Qt vets, пожалуйста, напишите ответ, если вы можете объяснить это лучше. я потратил немало времени на поиск этой информации, поэтому, пожалуйста, помогите кому-нибудь, если вы можете сделать лучше меня.

ответ

12

The documentation for moc заявляет, что в случае множественного наследования, класс обеспечения QObject должен появиться первый

Если вы используете множественное наследование, MOC предполагает, что первый наследуется класс является подклассом QObject. Кроме того, убедитесь, что только первый унаследованный класс является QObject.

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

Виртуальное наследование с QObject является не поддерживается.

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

Как это ни крути, если вы не ставите QObject сначала в список наследования, эта задача невозможна. Это ограничение в системе метаобъектов Qt. Если вы этого не сделаете, компилятор попытается применить некоторые элементы QObject как часть QXmlDefaultHandler.