QT 之信号槽

信号与槽是QT提供的一种事件处理机制

一、信号和槽

信号:用户对串口进行某些操作,导致窗口或控件发生某个事件。

严格来说 信号的本质就是事件

例如: 按钮单双击、窗口刷新、鼠标操作、键盘输入等等。

当触发事件之后,QT框架会调用根据事件对应的信号函数,而这个信号函数就是槽函数。

槽:在QT中,槽函数是一种特殊功能的函数,在编译过程也可以当作普通函数使用,之所以称为槽函数是因为其对应着QT框架中产生的信号处理。

1.1、信号与槽的关系

信号与槽其实都是独立的个体,本身并没有关系,但是因为某些特殊的需求则导致二者连接在一起,在QT中,使用QOjbect类中的connect函数进行二者连接。

cpp 复制代码
QMetaObject::Connection QObject::connect(

                const QObject *sender, const char *signal,

                const QObject *receiver, const char *method,

                Qt::ConnectionType type = Qt::AutoConnection)

sender : 发出信号的对象

signal : 信号函数地址

receiver: 信号接收者

method : 信号触发之后的对应的槽函数

1、connect函数相对于做了信号处理的注册

2、调用connect函数的sender对象的信号并没有产生,所有receiver对象的method也不会执行。

3、method槽函数本质是一个回调函数,触发一次信号则对应执行一次

4、connect中的sender和receiver两个指针必须实例化,不然不会成功。

1.2、标准信号槽使用

例子:

当按键按下时,关闭当前串口

connect(ui->pushButton, &QPushButton::clicked, this , &MainWindow::close)

其中 ui->pushButton 为按键对象 this为当前窗口。

&QPushButton::clicked 为按键按下触发信号,&MainWindow::close 则为按下之后处理的事情。

1.3、自定义信号槽使用

当QT提供的信号槽无法满足我们使用要求的时候,则需要自己去设计自己需求的信号与槽,还是使用connect进行对自定义的信号槽

如果想要自己定义信号槽,那么需要重新编写类让其继承Qt某些标准,自己编写的类想要使用信号槽则需要满足以下条件:

1、这个类必须从QObject类进行派生 2、在定义类头文件中加入Q_OBJECT宏

如下所示:

cpp 复制代码
class myMainWindow:public QWidget
{
    Q_OBJECT

    ...........
}

1.3.1 自定义信号

自定义信号则需要满足以下要求:

1、信号是类的成员函数

2、返回值是 void 类型

3、信号的名字可以根据实际情况而定

4、参数可以随意指定、信号也支持重载

5、信号需要使用signals关键字进行声明,使用方法类似于public等关键字

6、信号函数需要声明,不需要定义

7、在程序中发送自定义信号,发送信号的本质就是调用信号函数

-习惯性在信号函数前加上关键字:emit

-emit只是显示的声明一下信号被发送出去,没有特殊含义

-底层 emit == #define emit

例如:

cpp 复制代码
class test : public QObject
{
    Q_OBJECT
signals:
    void testsignals();
    //参数的作用在于传输数据。
    void testsignals(int a);
}

1.3.2 自定义槽

槽函数就是信号的处理动作,自定义槽函数与自定义函数写法一样的。

自定义槽函数要求

1、返回值是void类型

2、槽也是函数,支持重载

槽函数对应的参数与发送信号的参数一一对应

信号的参数可以大于等于槽函数的参数个数,当大于时则多余的数据被忽略了

3、Qt槽函数的类型

类的成员函数 全局函数 静态函数 lambda表达式(匿名函数)

4、槽函数可以使用关键字进行声明:slots

public slots: private slots: protected slots:

例如:

cpp 复制代码
class test : public QObject
{
public:
    void testSlots();
    static void testFun();
public slots:
    void tsetSlot(int id);
}

1.4 信号槽拓展

1、一个信号可以连接多个槽函数,发一个信号多个处理

需要写多个connect连接

槽函数的执行顺序是随机的,与connect的调用无关

信号的接收者可以是一个对象也可以是多个对象

2、一个槽函数可以连接多个信号,多个不同的信号,处理动作是相同的

写多个connect就可以

3、信号可以连接信号

信号接受者可以补不出来接收信号,继续发送新的信号->传递了数据并没有处理

4、信号槽是可以断开的

disconnect

1.5、lambad表达式

lambda表达式就是一个匿名函数,如法如下:

[capture](params)opt->{body;};

capture : 捕获列表

params : 参数列表

opt : 函数选项

ret : 返回值类型

body : 函数体

例如:

int ret = [](int a) -> int

{

return a+1;

}(100);

相关推荐
大白的编程日记.1 小时前
【计算机基础理论知识】C++篇(二)
开发语言·c++·学习
网小鱼的学习笔记1 小时前
python中MongoDB操作实践:查询文档、批量插入文档、更新文档、删除文档
开发语言·python·mongodb
Q_Q5110082851 小时前
python的保险业务管理与数据分析系统
开发语言·spring boot·python·django·flask·node.js·php
亮1111 小时前
Maven 编译过程中发生了 Java Heap Space 内存溢出(OutOfMemoryError)
java·开发语言·maven
Chef_Chen1 小时前
从0开始学习R语言--Day40--Kruskal-Wallis检验
开发语言·学习·r语言
Zhu_S W1 小时前
深入理解Java虚拟机:Java内存区域与内存溢出异常
java·开发语言·jvm
灰海1 小时前
原型与原型链到底是什么?
开发语言·前端·javascript·es6·原型模式·原生js
TechNomad1 小时前
Qt开发:QtConcurrent介绍和使用
qt
鸡蛋灌Bean2 小时前
Java常用设计模式大全
java·开发语言·设计模式
钮钴禄·爱因斯晨2 小时前
C语言 | 函数核心机制深度解构:从底层架构到工程化实践
c语言·开发语言·数据结构