是否有可能有一个模板类,它继承自QObject(并且在其声明中有Q_OBJECT宏)?
我想创建像插槽适配器这样的东西,它会做一些事情,但插槽可以采用任意数量的参数(参数数量取决于模板参数)。
我刚刚尝试过,并且遇到了链接器错误。我猜这个模板类没有调用gmake或moc。有没有办法做到这一点?也许通过显式实例化模板?
答案 0 :(得分:31)
无法混合模板和Q_OBJECT,但如果你有一个类型的子集,你可以列出这样的插槽和信号:
class SignalsSlots : public QObject
{
Q_OBJECT
public:
explicit SignalsSlots(QObject *parent = 0) :
QObject(parent) {}
public slots:
virtual void writeAsync(int value) {}
virtual void writeAsync(float value) {}
virtual void writeAsync(double value) {}
virtual void writeAsync(bool state) {}
virtual void writeAsync(svga::SSlideSwitch::SwitchState state) {}
signals:
void readAsynkPolledChanged(int value);
void readAsynkPolledChanged(float value);
void readAsynkPolledChanged(double value);
void readAsynkPolledChanged(bool state);
void readAsynkPolledChanged(svga::SSlideSwitch::SwitchState state);
};
...
template <class T>
class Abstraction : public SignalsSlots
{...
答案 1 :(得分:10)
考虑到一些限制:你可以。 首先请熟悉(如果已经不是)https://doc.qt.io/archives/qq/qq16-dynamicqobject.html。 - 这将有助于改变它。 关于限制:你可以有一个模板QObject类,即从QObject派生的模板类,但是:
希望这会有所帮助。
答案 2 :(得分:2)
仍然无法混合模板和Q_OBJECT,但根据您的使用情况,您可以使用新的“连接”语法。这至少允许使用模板槽。
经典的非工作方式:
class MySignalClass : public QObject {
Q_OBJECT
public:
signals:
void signal_valueChanged(int newValue);
};
template<class T>
class MySlotClass : public QObject {
Q_OBJECT
public slots:
void slot_setValue(const T& newValue){ /* Do sth. */}
};
所需用法但不可编辑:
MySignalClass a;
MySlotClass<int> b;
QObject::connect(&a, SIGNAL(signal_valueChanged(int)),
&b, SLOT(slot_setValue(int)));
错误:Q_OBJECT不支持模板类(For MySlotClass)。
解决方案使用新的'connect'语法:
// Nothing changed here
class MySignalClass : public QObject {
Q_OBJECT
public:
signals:
void signal_valueChanged(int newValue);
};
// Removed Q_OBJECT and slots-keyword
template<class T>
class MySlotClass : public QObject { // Inheritance is still required
public:
void slot_setValue(const T& newValue){ /* Do sth. */}
};
现在我们可以实例化所需的'MySlotClass'对象并将它们连接到适当的信号发射器。
MySignalClass a;
MySlotClass<int> b;
connect(&a, &MySignalClass::signal_valueChanged,
&b, &MySlotClass<int>::slot_setValue);
结论:可以使用模板插槽。发送模板信号不起作用,因为由于缺少Q_OBJECT而发生编译器错误。
答案 3 :(得分:1)
我试过显式实例化模板,并得到了这个:
core_qta_qt_publisheradapter.hpp:96:错误:Q_OBJECT不支持模板类
我猜这回答了我的问题。
修改强>
实际上,如果我将整个模板类定义放在头文件中,那么qt预处理器不会处理它,然后我会收到链接器错误。因此,如果我添加缺少的方法,必须可以这样做。
编辑#2
This library完全符合我的要求 - 使用自定义信号/插槽机制,其中插槽没有定义签名。