Как использовать ссылку на абстрактный класс в сигнале Qt? - PullRequest
1 голос
/ 31 января 2011

Предположим, у меня есть абстрактный базовый класс 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 &)));

Отладка показывает, что connect возвращает true.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2011

Если отправитель и получатель находятся в разных потоках, то соединение ставится в очередь, и с этим типом соединения вы не можете использовать ссылки, так как они не могут быть скопированы. Так как вы не указали тип соединения, когда вызывали * 1001, * тип соединения установлен на 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"
0 голосов
/ 31 января 2011

Макросы 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&)));
...