2012-06-05 32 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); 

希望这对你有所帮助。 谢谢