Qt消息的理解

分析

信号是什么,信号与槽(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();
}

执行情况:

image.png

总结

官网这样说:

当对象的内部状态以某种方式发生变化,对象的客户端或所有者可能会感兴趣时,对象就会发出信号。信号是公共访问函数,可以从任何地方发出,但我们建议只从定义信号及其子类的类发出信号。
当发出信号时,连接到它的槽通常立即执行,就像普通的函数调用一样。当这种情况发生时,信号和槽机制完全独立于任何GUI事件循环。一旦所有槽都返回,emit语句之后的代码就会执行。当使用排队连接时,情况略有不同;在这种情况下,emit关键字后面的代码将立即继续执行,而插槽将稍后执行。
如果多个插槽连接到一个信号,则在信号发出时,这些插槽将按照它们连接的顺序依次执行。
信号是由moc自动生成的,不能在.cpp文件中实现。它们永远不能有返回类型(即使用void)。
关于参数的注意事项:我们的经验表明,如果信号和槽不使用特殊类型,它们的可重用性会更好。如果QScrollBar::valueChanged()使用一个特殊类型,比如假设的QScrollBar::Range,那么它只能连接到专门为QScrollBar设计的槽。将不同的输入部件连接在一起是不可能的。

通过上面可知,一些地方与官网说的不一样,官网说,信号不能有返回值,实际是可以用返回值的。

官网这样说的:

image.png

显然说得不准确,官网从理论上说了信号与槽

那作为程序员应该怎么理解这东西,简单的理解,就是就是两个函数的关联,信号是一个特殊的函数,槽是一个普通的函数,通过connect进行了关联。

如果在不同线程间,信号就是放到了队列中

在同一个线程中,就是直接通过信号调用槽函数。

就是这么简单。

最后,以图做总结:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/maokexu123/article/details/130725001
今日推荐