如何在 Qt 信号中使用对抽象类的引用?
Posted
技术标签:
【中文标题】如何在 Qt 信号中使用对抽象类的引用?【英文标题】:How to use a reference to an abstract class in a Qt signal? 【发布时间】:2011-01-31 13:59:13 【问题描述】:假设我有一个抽象基类Foo
,我想在信号中使用对它的引用:
void FooUpdated(Foo &);
这不起作用,匹配的槽永远不会被调用。有没有办法实现这一点,或者我必须使用指针来代替(它与指针一起使用)。
编辑 - 代码
信号(IDecodedFrame
是抽象的):
void ShowFrameSignal( IDecodedFrame & DecodedFrame );
插槽:
virtual void ShowFrame( IDecodedFrame & DecodedFrame );
连接:
connect(this, SIGNAL(ShowFrameSignal(libCommon::IDecodedFrame &)),
sink, SLOT(ShowFrame(libCommon::IDecodedFrame &)));
调试显示连接返回true
。
【问题讨论】:
插槽长什么样,信号和插槽是怎么连接的? @Frank:添加了连接的定义和代码。 如果不查看文档,我不确定答案,但我敢打赌,IDecodedFrame 需要从另一个 Qt 基类派生并实现一些必需的功能。可能是一个复制构造函数来获得安全复制。 【参考方案1】:SIGNAL
和 SLOT
宏不需要引用符号 (&
)。我不确定这是否是它的绊脚石,但以下使用抽象类引用的示例对我有用:
#include <QtCore>
#include <QtDebug>
class ISignalable
public:
virtual void Go() const = 0;
;
class Signalable : public ISignalable
public:
void Go() const qDebug() << "Go!";
;
class Caller : public QObject
Q_OBJECT
public:
void CallSignal(const ISignalable &obj) const RunSignal(obj);
signals:
void RunSignal(const ISignalable &obj) const;
;
class Sink : public QObject
Q_OBJECT
public slots:
void HandleSignal(const ISignalable &obj) const
obj.Go();
;
int main (int argc, char ** argv)
QCoreApplication app(argc, argv);
Caller c;
Sink s;
QObject::connect(&c, SIGNAL(RunSignal(ISignalable)),
&s, SLOT(HandleSignal(ISignalable)));
Signalable obj;
c.CallSignal(obj);
return app.exec();
#include "main.moc"
这也有效:
QObject::connect(&c, SIGNAL(RunSignal(const ISignalable&)),
&s, SLOT(HandleSignal(const ISignalable&)));
但这不起作用:
QObject::connect(&c, SIGNAL(RunSignal(ISignalable&)),
&s, SLOT(HandleSignal(ISignalable&)));
【讨论】:
"SIGNAL 和 SLOT 宏不需要引用符号 (&)" - 它们用于非常量引用。只有 const 参考。和 copy 等价于信号/槽。【参考方案2】:如果发送方和接收方在不同的线程中,则连接将排队,并且对于这种类型的连接,您不能使用引用,因为它们不能被复制。由于您在调用connect()
时未提供连接类型,因此连接类型设置为Qt::AutoConnection
,并且在调用connect()
时未知信号的传递(读取调用槽)是否成功。
顺便说一句,这对我有用:
#include <QtCore/QCoreApplication>
#include <QDebug>
class Abstract : public QObject
Q_OBJECT
public:
virtual ~Abstract() ;
virtual void abstract() = 0;
;
class Test : public QObject
Q_OBJECT
public:
Test()
connect(this, SIGNAL(aSignal(Abstract &)),
this, SLOT(aSlot(Abstract &)));
;
void test()
emit aSignal(*static_cast<Abstract*>(0));
signals:
void aSignal(Abstract & abstract);
public slots:
virtual void aSlot(Abstract & abstract)
qDebug() << "slot was called";
;
;
int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
Test aTest;
aTest.test();
return app.exec();
#include "main.moc"
【讨论】:
以上是关于如何在 Qt 信号中使用对抽象类的引用?的主要内容,如果未能解决你的问题,请参考以下文章
接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map