【Qt】信号与槽
创始人
2025-01-15 12:33:39
0次

目录

一. 什么是信号/槽 

二. 连接信号与槽

1. 代码实现

Qt4版本的写法

Qt5写法

2. 图形化开发

三. 自定义信号

四. 带参数的信号&槽

五. 断开信号与槽的连接

六. lambda表达式的槽函数


如果一个类要使用信号与槽机制,需要在声明处使用Q_OBJECT宏

一. 什么是信号/槽 

信号(Signal)和槽(slot)是Qt的一个强大的机制,用于处理对象之间的通信。

允许一个对象(发送者)发出信号,另一个对象(接受者)在该信号被发出时执行特定的槽函数

  • 信号 

    ​​​​​​​ssca

    信号的图标是

  •  槽

    ​​​​​​​槽是普通的成员函数,用于响应信号发出的事件

    槽可以是任何公共的函数,不同于信号,槽需要定义实现

    槽的图标是​​​​​​​

二. 连接信号与槽

1. 代码实现

在Qt中,通过QObject::connect()函数将信号与槽关联起来,实现控件对象之间的通信

示例:针对 button 这个按钮,点击后,改变窗口标题

Qt4版本的写法

注意,connect的第二个参数和第四个参数都是const char*,但调用时,我们传参都是函数指针。其实const char*的connect函数是Qt4的写法,其在调用时还需要对参数进行转换

//Qt5写法 connect(button, &QPushButton::clicked, this, &Widget::handleClicked); //Qt4写法 connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::handleClicked));

SIGNAL宏和SLOT宏,将函数指针的类型转化为const char*;

在槽函数声明时,也有独特的关键字——slots

访问限定符(public/protected/private) + slots  其后的成员函数都会被qmake识别为槽函数

Qt5写法

在Qt5中,使用了泛型编程,对connect函数做了重载 

 需要保证signal信号时sender的成员函数,slot是receiver的成员函数,否则会编译出错

2. 图形化开发

将按钮拖拽到程序界面,右键按钮控件,选择转到槽

会显示当前按钮控件都有哪些信号——选择clicked()

Qt会帮我们完成槽函数的声明和定义,只需要我们实现具体功能即可

 实际上,是qmake生成的ui_widget.h文件中调用了connectSlotsByName,帮我们关联和信号与槽,如果更改自动生成的槽函数的函数名,connectSlotsByName将无法完成关联。自动生成的槽函数的命名指明了信号产生者和信号类型

三. 自定义信号

在Qt中,信号本质也是函数,Qt允许用户自定义信号,但只能声明,信号的实现要交由Qt实现。信号函数的定义,是Qt在编译过程中自动生成的,我们无法干预,其实现要配合Qt框架做很多既定操作。

Qt规定,信号函数的返回值必须是void,参数随意,可无参数,也可通过参数进行重载

定义信号函数的关键字——signals

发送信号的关键字——emit

但是在Qt5后,又做了更新。将实际发送信号的逻辑直接写在了信号的定义中。所以不用emit,而是直接调用信号函数,也可以发送信号 

四. 带参数的信号&槽

传参可以起到服用代码的效果,如果多个逻辑,逻辑整体一致,只有涉及的数据不同,那可以通过函数-参数来服用代码,在不同场景传入不同参数即可,公有一套信号与槽

 Qt规定:信号的参数个数 >= 其关联的槽的参数个数

一个槽函数,可能关联多个信号,如此可以使得信号和槽的绑定更加灵活,多余的参数直接丢弃即可,但必须确保槽每个参数都有传参

示例:

#ifndef WIDGET_H #define WIDGET_H  #include   QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE  class Widget : public QWidget {     Q_OBJECT  signals:     void mySignal(const QString&);//信号函数的声明  public:     Widget(QWidget *parent = nullptr);     ~Widget();     void handleMySignal(const QString&);//槽函数声明  private:     Ui::Widget *ui; }; #endif // WIDGET_H

五. 断开信号与槽的连接

Qt还提供取消已关联的信号与槽的方法——disconnect函数

disconnect的使用与connect非常类似,实际使用比较少,大部分情况下,关联好的信号与槽就不会再做改变了

其参数同connect,只是实际效果不同:

connect是将sender发出的signal信号,由receiver的slot函数处理

而disconnect是将sender发出的signael信号,和receive的slot函数取消关联关系

六. lambda表达式的槽函数

槽函数也可以使用lambda表达式简化编写,不需要像传统的槽函数那样声明定义。

Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);     QPushButton *button = new QPushButton(this);     button->setText("QDebug打印输出");     button->move(250, 250);      connect(button, &QPushButton::clicked, this, [](){        qDebug() << "lambda表达式的槽函数";     }); }

注意lambda表达式的参数同样遵循上述规则——参数个数小于等于信号的参数个数

同时,lambda表达式捕获参数建议值捕获,因为在函数中一般控件对象使用指针管理,但因为挂接对象树的原因,出了函数控件对象并没有销毁,但指针是不可用的,所以在lambda表达式中捕获参数建议使用值捕获

相关内容

热门资讯

每日必看!江岸多玩到底能开挂吗... 每日必看!江岸多玩到底能开挂吗(辅助挂),江岸多玩原来真的有辅助挂讲义1、江岸多玩脚本辅助下载、江岸...
玩家交流!颖河竞技怎么开挂(外... 玩家交流!颖河竞技怎么开挂(外挂),颖河竞技好像是有外挂教材一、颖河竞技游戏安装教程牌型概率发牌机制...
最新通报!皮皮四川麻将软件下载... 最新通报!皮皮四川麻将软件下载(辅助挂),皮皮四川麻将果然有辅助挂模块1、操作简单,无需皮皮四川麻将...
一分钟揭秘!52游戏开挂脚本(... 一分钟揭秘!52游戏开挂脚本(透视挂),52游戏切实有透视挂法子52游戏脚本下载中分为三种模型:52...
一分钟快速了解!堆堆乐开挂破解... 一分钟快速了解!堆堆乐开挂破解(外挂),堆堆乐竟然真的有外挂方针1、下载好堆堆乐正确养号方法之后点击...
重大通报!汇城贵州麻将开挂脚本... 重大通报!汇城贵州麻将开挂脚本(开挂),汇城贵州麻将原来真的有开挂法门1、重大通报!汇城贵州麻将开挂...
盘点一款!七色城透视挂件(外挂... 盘点一款!七色城透视挂件(外挂),七色城切实是真的有外挂经验1、全新机制【七色城ai辅助工具激活码】...
今日头条!多多休闲透视软件下载... 今日头条!多多休闲透视软件下载(外挂),多多休闲确实是真的有外挂攻略1、首先打开多多休闲辅助器下载最...
关于!钱柜麻将真的有透视吗(辅... 关于!钱柜麻将真的有透视吗(辅助器),钱柜麻将一贯是有辅助器练习钱柜麻将能透视中分为三种模型:钱柜麻...
今日焦点!河北家乡棋牌辅助工具... 今日焦点!河北家乡棋牌辅助工具(外挂),河北家乡棋牌果然是有外挂手册小薇(辅助器软件下载)致您一封信...