2011-01-31 4 views
1

Предположим, у меня есть абстрактный базовый класс Foo, и я хочу использовать ссылку, что в сигнале:Как использовать ссылку на абстрактный класс в сигнале Qt?

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.

+0

Как слот выглядеть, и как подключить сигнал и слот? –

+0

@Frank: добавлены определения и код для подключения. –

+0

Я не уверен в ответе, не оглядываясь в документации, но я уверен, что IDecodedFrame должен получить из другого базового класса Qt и реализовать некоторые требуемые функции. Возможно, конструктор копирования, чтобы получить безопасное копирование. –

ответ

0

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

«Макросы SIGNAL и SLOT не нуждаются в эталонном символе (&)» - они выполняют для неконстантных ссылок. Только _const_ ref. и копия эквивалентны сигналу/слотам. –

0

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