[英]How create Interface for QObject class
I want to create an interface for QObject
class with signal/slot system.我想用信号/槽系统为
QObject
class 创建一个接口。
The code below works but has a disadvantage: Interface inherits QObject
and has no Q_OBJECT
macro.下面的代码有效但有一个缺点:接口继承
QObject
并且没有Q_OBJECT
宏。
I want to make a pure virtual interface, so InterfaceClass
shouldn't have a constructor.我想制作一个纯虚拟接口,所以
InterfaceClass
不应该有构造函数。 But in RealisationClass
I cannot call QObject
(error: type 'QObject' is not a direct base of 'RealisationClass') nor InterfaceClass
(It hasn't constructor InterfaceClass(QObject* parent)
) constructors.但是在
RealisationClass
中,我无法调用QObject
(错误:类型“QObject”不是“RealisationClass”的直接基础)或InterfaceClass
(它没有构造函数InterfaceClass(QObject* parent)
)构造函数。 Moreover I cannot add Q_OBJECT
macro in InterfaceClass
(error: undefined reference to 'vtable' for InterfaceClass')此外,我无法在
InterfaceClass
中添加Q_OBJECT
宏(错误:未定义对 InterfaceClass 的“vtable”的引用)
So, how should I change classes to add QObject()
constructor in RealisationClass
and add Q_OBJECT
macro (or remove QObject
inheritance) to InterfaceClass.那么,我应该如何更改类以在
RealisationClass
中添加QObject()
构造函数并将Q_OBJECT
宏(或删除QObject
继承)添加到 InterfaceClass。
IntefaceClass.h:接口类.h:
#ifndef INTERFACE_CLASS_H
#define INTERFACE_CLASS_H
#include <QObject>
class InterfaceClass : public QObject {
Q_OBJECT
public:
virtual ~InterfaceClass(){};
virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(InterfaceClass, "Interface")
#endif // INTERFACE_CLASS_H
RealisationClass.h:实现类.h:
#include <QObject>
#include <QDebug>
#include "InterfaceClass.h"
class RealisationClass : public InterfaceClass {
Q_OBJECT
Q_INTERFACES(InterfaceClass)
public:
explicit RealisationClass(QObject* parent = nullptr){};
void foo() override {qDebug() << "Hello, world";};
};
main.cpp:主.cpp:
#include <QCoreApplication>
#include "RealisationClass.h"
#include "InterfaceClass.h"
#include <QObject>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer everySecondTimer;
everySecondTimer.setInterval(1000);
QScopedPointer<InterfaceClass> interfacePointer(new RealisationClass);
QObject::connect(&everySecondTimer, &QTimer::timeout, interfacePointer.get(), &InterfaceClass::foo);
everySecondTimer.start();
return a.exec();
}
Q_OBJECT macro problem has another reason: I don't add InterfaceClass.h as target to Cmake's AUTOMOC (qmake (moc) didn't handle this file). Q_OBJECT 宏问题还有另一个原因:我没有将 InterfaceClass.h 作为目标添加到 Cmake 的 AUTOMOC(qmake (moc) 没有处理这个文件)。
Using interfaces with QObject
hierarchies is a real pain.使用具有
QObject
层次结构的接口是一个真正的痛苦。 You often want your interface to have some features of QObject
(ie. signals/slots, destroyed signal, integrates with Qt APIs) but have it be a lightweight interface definition.您通常希望您的接口具有
QObject
的某些功能(即信号/槽、销毁信号、与 Qt API 集成),但它是一个轻量级的接口定义。 Unless Qt is refactored so that an IQObject
exists that is used throughout the Qt code-base, you can't get a perfect solution.除非重构
IQObject
以便存在在整个 Qt 代码库中使用的 IQObject,否则您无法获得完美的解决方案。 What I recommend is to simply forward all constructor calls through to QObject
:我推荐的是简单地将所有构造函数调用转发给
QObject
:
#ifndef INTERFACE_CLASS_H
#define INTERFACE_CLASS_H
#include <QObject>
class InterfaceClass : public QObject {
Q_OBJECT
public:
using QObject::QObject; // <<--------
virtual ~InterfaceClass(){};
virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(InterfaceClass, "Interface")
#endif // INTERFACE_CLASS_H
With the using QObject::QObject
line, InterfaceClass
now has constructors with the same declarations as QObject
.通过
using QObject::QObject
行, InterfaceClass
现在具有与QObject
具有相同声明的构造函数。 All they do is forward the call to QObject
.他们所做的就是将调用转发给
QObject
。 With that, you can now do this in RealisationClass
:有了它,您现在可以在
RealisationClass
中执行此操作:
#include <QObject>
#include <QDebug>
#include "InterfaceClass.h"
class RealisationClass : public InterfaceClass {
Q_OBJECT
Q_INTERFACES(InterfaceClass)
public:
explicit RealisationClass(QObject* parent = nullptr)
: InterfaceClass(parent) // <<------
{};
void foo() override {qDebug() << "Hello, world";};
};
This has two major downsides:这有两个主要缺点:
I still need to play around with virtual inheritance ( class InterfaceClass: public virtual QObject
) to see if that can solve #2 without introducing other issues.我仍然需要尝试使用虚拟 inheritance (
class InterfaceClass: public virtual QObject
) 看看是否可以在不引入其他问题的情况下解决#2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.