分析
信号是什么,信号与槽(Signals&Slot)是QT编程的基础,也是Qt的一大创新。因为有了信号与槽的编程机制,在Qt中处理界面各个组件的交互操作变得更加直观和简单。
信号(signal)就是特定下被发射的事件。
槽就是对信号响应的函数,槽就是一个函数,与一般的C++函数是一样,可以定义在类的任何部分,可以具有任何参数,也可以被直接调用。
下面写一个例子,描述一下,没用官网的,官网的有些不容易理解:
头文件:
#ifndef SIGNALEXAMPLE_H
#define SIGNALEXAMPLE_H
#include <QObject>
class SignalExample : public QObject
{
Q_OBJECT
public:
SignalExample(QObject *parent = nullptr);
void send();
void send2();
signals:
void sendSignal1(int newValue);
int sendSignal2(int newValue);
public slots:
void receiveSignal1(int value);
int receiveSignal2(int value);
};
#endif // SIGNALEXAMPLE_H
CPP文件:
#include "signalexample.h"
SignalExample::SignalExample(QObject *parent) : QObject(parent)
{
QObject::connect(this, &SignalExample::sendSignal1,
this, &SignalExample::receiveSignal1);
QObject::connect(this, &SignalExample::sendSignal2,
this, &SignalExample::receiveSignal2);
}
void SignalExample::send()
{
emit sendSignal1(10);
}
void SignalExample::send2()
{
qDebug("enter function send2");
int a = sendSignal2(10);
qDebug("exit function send2 a=%d", a);
}
void SignalExample::receiveSignal1(int value)
{
qDebug("enter function SignalExample::receiveSignal1 value=%d", value);
qDebug("exit SignalExample::receiveSignal1");
}
int SignalExample::receiveSignal2(int value)
{
return value;
}
main函数:
#include <QCoreApplication>
#include <signalexample.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
SignalExample signalExampleA;
signalExampleA.send();
signalExampleA.send2();
return a.exec();
}
执行情况:
总结
官网这样说:
当对象的内部状态以某种方式发生变化,对象的客户端或所有者可能会感兴趣时,对象就会发出信号。信号是公共访问函数,可以从任何地方发出,但我们建议只从定义信号及其子类的类发出信号。
当发出信号时,连接到它的槽通常立即执行,就像普通的函数调用一样。当这种情况发生时,信号和槽机制完全独立于任何GUI事件循环。一旦所有槽都返回,emit语句之后的代码就会执行。当使用排队连接时,情况略有不同;在这种情况下,emit关键字后面的代码将立即继续执行,而插槽将稍后执行。
如果多个插槽连接到一个信号,则在信号发出时,这些插槽将按照它们连接的顺序依次执行。
信号是由moc自动生成的,不能在.cpp文件中实现。它们永远不能有返回类型(即使用void)。
关于参数的注意事项:我们的经验表明,如果信号和槽不使用特殊类型,它们的可重用性会更好。如果QScrollBar::valueChanged()使用一个特殊类型,比如假设的QScrollBar::Range,那么它只能连接到专门为QScrollBar设计的槽。将不同的输入部件连接在一起是不可能的。
通过上面可知,一些地方与官网说的不一样,官网说,信号不能有返回值,实际是可以用返回值的。
官网这样说的:
显然说得不准确,官网从理论上说了信号与槽
那作为程序员应该怎么理解这东西,简单的理解,就是就是两个函数的关联,信号是一个特殊的函数,槽是一个普通的函数,通过connect进行了关联。
如果在不同线程间,信号就是放到了队列中
在同一个线程中,就是直接通过信号调用槽函数。
就是这么简单。
最后,以图做总结: