如何在 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】:

SIGNALSLOT 宏不需要引用符号 (&)。我不确定这是否是它的绊脚石,但以下使用抽象类引用的示例对我有用:

#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 信号中使用对抽象类的引用?的主要内容,如果未能解决你的问题,请参考以下文章

来自两个抽象类的多重继承 (Qt)

接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map

使用 findAll() 方法时如何避免休眠创建抽象类的对象?

提升引用成员抽象类的序列化

抽象类

JAVA抽象类的定义与使用