开发者

How to use a reference to an abstract class in a Qt signal?

开发者 https://www.devze.com 2023-02-07 12:21 出处:网络
Suppose I have an abstract base class Foo, and I want to use a reference to that in a signal: void FooUpdated(Foo &);

Suppose I have an abstract base class Foo, and I want to use a reference to that in a signal:

void FooUpdated(Foo &);

This does not work, the matching slot is never invoked. Is there a way to achieve this, or do I have to use a pointer instead (it works with a pointer).

Edit - Code

The signal (IDecodedFrame is abstract):

void ShowFrameSignal( IDecodedFrame & DecodedFrame );

The 开发者_开发问答slot:

virtual void ShowFrame( IDecodedFrame & DecodedFrame );

The connection:

connect(this, SIGNAL(ShowFrameSignal(libCommon::IDecodedFrame &)),
        sink, SLOT(ShowFrame(libCommon::IDecodedFrame &)));

Debugging reveals that connect returns true.


The SIGNAL and SLOT macros do not need the reference symbol (&). I'm not sure if that is what is tripping it up or not, but the following example of using a reference to an abstract class is working for me:

#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"

This also works:

QObject::connect(&c, SIGNAL(RunSignal(const ISignalable&)),
                 &s, SLOT(HandleSignal(const ISignalable&)));

But this does not work:

QObject::connect(&c, SIGNAL(RunSignal(ISignalable&)),
                 &s, SLOT(HandleSignal(ISignalable&)));


If sender and receiver are in different threads then the connection is queued and with this type of connection you can't use references as they can't be copied. As you didn't supply connection's type when you called connect() connection's type is set to Qt::AutoConnection and it's unknown wheather signal's delivery (read calling slot) will succeed or not at the time connect() is called.

By the way, this works for me:

#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"
0

精彩评论

暂无评论...
验证码 换一张
取 消