我有一个类(MyClass
)从Qt内置对象(QGraphicsTextItem
)继承了它的大部分功能。 QGraphicsTextItem
间接从QObject
继承。 MyClass
还实现了一个界面MyInterface
。
class MyClass : public QGraphicsTextItem, public MyInterface
我需要能够在connect
上使用disconnect
和MyInterface*
。但似乎connect
和disconnect
仅适用于QObject*
个实例。由于Qt不支持来自QObject派生类的多重继承,因此我无法从MyInterface
派生QObject
。 (无论如何,这对于界面也没有多大意义。)
有一个discussion of the problem online,但IMO提出的解决方案在常见情况下(通过其接口访问对象)相当无用,因为您无法连接来自MyInterface*
的信号和插槽但必须强制转换它到派生类型。由于MyClass
是许多MyInterface
派生类中的一个,因此如果 - 这个 - 转换为此其他 - 如果 - 那个 - 转换为该语句,则需要“代码异味”打败了界面的目的。
这个限制是否有一个很好的解决方案?
更新:我注意到,如果我dynamic_cast
MyInterface*
到QObject*
(因为我知道全部MyInterface
} -derived类最终也从QObject
继承,它似乎有用。那就是:
MyInterface *my_interface_instance = GetInstance();
connect(dynamic_cast<QObject*>(my_interface_instance), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));
但是这个真的似乎我要求未定义的行为......
答案 0 :(得分:12)
您自己找到了答案:dynamic_cast正如您所期望的那样工作。它不是未定义的行为。如果您获得的MyInterface实例不是QObject,则转换将返回null并且您可以保护自己(这不会发生,因为您说接口的所有实例也是QObjects)。但请记住,您需要启用RTTI才能使其正常工作。
我还会提出一些其他建议:
使用 Q_INTERFACES 功能(它不仅适用于插件)。然后,当真正需要时,您将使用QObject并使用qobject_cast查询MyInterface。我不太详细地了解你的问题,但既然你知道所有的MyInterface实例都是QObjects,这似乎是最明智的方法。
向MyInterface添加QObject* asQObject()
抽象方法,并在所有子类中将其实现为{ return this; }
。
拥有 QGraphicsTextItem(组合)而不是 一个(继承)。
答案 1 :(得分:7)
您可以声明在其构造函数中包含QObject的MyInterface:
class MyInterface {
public:
MyInterface(QObject * object);
QObject * object() { return m_object; }
...
private:
QObject * m_object;
};
MyInterface::MyInterface(QObject * object) :
m_object(object)
{
...
}
然后在MyClass构造函数中:
MyClass::MyClass() :
MyInterface(this)
{
...
}
你可以连接信号:
MyInterface *my_interface_instance = GetInstance();
connect(my_interface_instance->object(), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));