2012-06-05 28 views
2

我有一個帶插槽的X類,帶有信號的Y類。我從類X建立連接,並在類Y中創建一個公共方法來發出類X的信號(我不確定這一步是否必要)。Qt信號和不同類別的插槽

然後,如果我從類X調用該方法,則會發出信號並執行插槽。但是如果我從Y類發出信號,插槽就不會執行,我不明白爲什麼。

我還可以在Y類建立連接嗎?

這個僞代碼試圖解釋什麼,我想:

class X : public QWidget { 
    Q_OBJECT 

X(){ 
    connect(Y::getInstance(), SIGNAL(updateSignal(int)), this, SLOT(updateStatus(int))); 
    Y::getInstance().emitSignal(someValue); // Works 
} 

public slots: 
    void updateStatus(int value); 

} 

class Y : public QObject { 

Q_OBJECT 

Y(){ 

} 

public: 
    Y getInstance(); 
    void emitSignal(int value) { 
     emit updateSignal(value); 
    } 


signal: 
    void updateSignal(int value); 
} 

class Z : public Y { 
Z(){ 

} 

init(){ 
emitSignal(someValue); // Doesn't work 
} 
} 
+1

你能提供一些代碼嗎?我不能完全理解你想說的話 – alegen

+0

不,你只需要建立連接一次。請發佈一些你的代碼。 – Ammar

+0

這是非常複雜的代碼,所以我會發布一些僞代碼來更好地解釋這個問題 –

回答

4

請記住,連接不在之間,但在實例之間。如果您發出信號並期望調用連接的插槽,則必須在已建立連接的實例上發出。那是你的問題。

假設Y是Singleton

如果你在某些時候做connect(Y::getInstance(), ...)

Y::getInstance()確實new Y(),則Y的構造函數被調用之前建立連接。像這樣,信號將被髮射,但該時隙不會聽它。

除此之外,這將是最好做下面的事情之一,但你不能在Y的構造與這些方法發出信號:

  • 使用既知道第三等級Z X和Y,並進行連接
  • 依賴注入。這意味着X獲得在其構造的Y實例:

例如,對於依賴注入構造:

X::X(Y* const otherClass) 
{ 
    connect(otherClass, SIGNAL(...), this, SLOT(...) 
} 
0

您從構造發射信號。根據這段代碼片段,當時Y::getInstance()沒有意義。

+0

這只是一個簡化。我確實得到了Y實例。如果沒有,我不會說放射信號從X –

+0

作品是的。你從X調用'Y :: getInstance()。emitSignal(someValue);'它的效果,因爲那時你有一個Y對象,但是你不能從Y的構造函數中做到這一點。 – shan

+0

好吧,它不在構造函數中發生,它發生在Y代碼的其他部分。無論如何,我不明白爲什麼我不能從Y的構造函數中調用Y的方法 –

1

其簡單。請看下面的例子。

如果你想寫信號在自己的類&插槽,需要滿足兩個條件......

1. Your class must inherit from QObject class or any class derived from QObject. 

2. The Q_OBJECT macro must appear in a private section in your class.

/* Sender.h */ 

#ifndef SENDER_H 
#define SENDER_H 

#include <QObject> 

class Sender : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit Sender(QObject *parent = 0);  
    void fireSignal(); 

signals: 
    void foo(const QString& arg); 
}; 

#endif // SENDER_H 


/* Sender.cpp*/ 


#include "Sender.h" 

Sender::Sender(QObject *parent) : 
    QObject(parent) 
{ 
} 


void Sender::fireSignal() 
{ 
    emit foo("This a message sender is sending to receiver."); 
} 
以下

現在接收器的代碼

/* Receiver.h */ 

#ifndef RECEIVER_H 
#define RECEIVER_H 

#include <QObject> 

class Receiver : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit Receiver(QObject *parent = 0); 

public slots: 
    void bar(const QString& arg); 

}; 

#endif // RECEIVER_H 

/* Receiver.cpp */ 

#include "Receiver.h" 
#include <iostream> 

Receiver::Receiver(QObject *parent) : 
    QObject(parent) 
{ 
} 


void Receiver::bar(const QString &arg) 
{ 
    std::cout << arg.toStdString(); 
} 

現在的main.cpp代碼

#include <QtCore/QCoreApplication> 
#include "Sender.h" 
#include "Receiver.h" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    Sender sender; 
    Receiver receiver; 

    QObject::connect(&sender, SIGNAL(foo(QString)), &receiver, SLOT(bar(QString))); 

    sender.fireSignal(); 

    return a.exec(); 
} 

就是這樣。

最後如果你想使用另一種連接方法的語法。請使用下面的線

QObject::connect(&sender,&Sender::foo,&receiver,&Receiver::bar); 

希望這對你有所幫助。 謝謝