信号槽机制

目录

信号槽机制

Qt 中的信号

槽函数

槽函数定义

通过代码创建槽函数

通过ui文件创建槽函数

自定义信号

带参数的信号与槽

信号槽断开绑定


信号槽机制

信号和槽机制是 Qt 中一个非常重要的一个机制, 因为有信号和槽机制, 就可以通过某些条件的触发来调用这些槽函数, 而槽函数实际上也就是回调函数.

Qt 中的信号

  • 信号源: 信号源表示的是由哪一个控件发出信号

  • 信号的类型: 用户的不同的操作,可能触发不同的信号 点击的话, 就会触发被点击的信号 输入框中移动光标, 会触发移动光标的信号 以及勾选复选框等也会触发信号

  • 信号的处理方式: 槽函数(slot) -> 回调函数

  • 绑定信号与槽: connect 函数

Qt 中的信号实际上就是 Qt 中类的一些函数, 但是我们也可以自己实现信号的函数, 声明信号函数的时候需要写明 signals, 而再信号的定义中,其实是不需要定义的, 我们只需要声明即可

当我们需要发射信号的时候,我们需要写明 emit 但是现在也可以不写 emit 但是为了可读性, 我们还是建议写清楚

槽函数

槽函数就是一个函数, 这个函数用于处理当某个信号到来之后的任务, 所以槽函数实际上是很早就定义出来的, 再信号被触发之前定义出来的.

槽函数也是可以我们自己定义的, 不过 Qt 中也内置了一些槽函数, 比起信号自定义来说, 槽函数的自定义是更常见的.

槽函数的自定义是很简单的, 只需要再声明参函数前加一个 public slots , 不过现在也可以不写 public slots

槽函数定义

通过代码创建槽函数

下面我们实现一个案例: 我们可以创建一个按钮, 按下按钮后, 就会修改窗口的标题.

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
​// 1. 创建一个 QpushButtonQPushButton* button = new QPushButton(this);button->setText("按钮");button->move(200, 200);// 2. 绑定信号与槽函数connect(button, &QPushButton::clicked, this, &MainWindow::process_clicked);
}
​
​
void MainWindow::process_clicked()
{// 当点击按钮的时候吗,就会调用这个槽函数// 槽函数中修改窗口标题
​this->setWindowTitle("窗口标题被修改");
}

在 MainWindow 中声明的时候, 可以像普通函数一样声明, 也可以在槽函数前面添加 public slots

这个代码的作用就是可以修改窗口的标题, 在按钮被按下的时候

通过ui文件创建槽函数

上面我们通过代码的方式来创建了槽函数,但是我们也可以使用ui文件的方式来创建槽函数,具体怎么样,我们下面看.

首先我们需要在ui界面上拖拽一个按钮:

然后我们右键点击按钮,此时就会弹出一个框, 我们选择里面的转到槽

此时就会弹出一个对话框

这里面就是关于 QPushButton 中的所有的槽函数, 我们选择 clicked 函数,此时 Qt 就会自动帮我们生成一个槽函数,并且不需要我们手动的调用 connect 函数.

void Widget::on_pushButton_clicked()
{}

这个函数的命名是有规则的, 其中 on 开头,然后是控件名, 后面是相关的槽函数,而 Qt 就是根据这个函数名调用的这个槽函数, 所以当这个函数名被修改后,信号出发后也就不会调用对应的槽函数了.

自定义信号

虽然信号也可以自定义, 但是实际上自定义信号是很少见的, 因为Qt中自带的信号已经可以满足绝大多数的场景了, 而槽函数的自定义才是最常见的

而Qt中的信号,实际上也就是所谓的成员函数, 但是在信号的声明中,就需要在函数声明前写 signals, 而且信号是只需要声明的,不需要我们自己定义.

信号函数的返回值必须是 void 的,但是参数的话,是没有限制的.

下面我们写一个案例,这个案例就是通过按钮来修改窗口标题, 但是按钮的槽函数中并不执行修改窗口标题的任务, 按钮对应的槽函数中进行发射自定义信号, 自定义信号中绑定的槽函数进行修改窗口标题.

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
​// 绑定 my_signal 信号和自定义槽函数// my_signal 是自定义信号connect(this, &Widget::my_signal, this, &Widget::handle_my_signal);// handle_my_signal 是自定义槽函数
}
​
// 按钮对应的槽函数
void Widget::on_pushButton_clicked()
{// 点击按钮会触发该函数// 该函数中进行发射 my_signal 信号emit my_signal();
}
// my_signal 对应的槽函数
void Widget::handle_my_signal()
{// 在自定义槽函数中进行修改窗口标题this->setWindowTitle("通过自定义槽函数修改窗口标题");
}

槽函数的声明和信号的声明

class Widget : public QWidget
{Q_OBJECT
​
public:Widget(QWidget *parent = nullptr);~Widget();
​
signals:// 信号声明void my_signal();
​
private slots:// 槽函数声明void on_pushButton_clicked();
​void handle_my_signal();
​
private:Ui::Widget *ui;
};

带参数的信号与槽

信号和槽实际上也就是一种函数,既然是函数,那么也就是一定可以有参数,那么信号和槽的参数需要怎么传递呢?

实际上信号和槽函数的参数是有一定关系的,对于信号函数而言,绑定的槽函数的参数是需要与信号的参数是一致的,或者信号的参数多于槽函数的参数。

那么为什么需要带参数呢?带参数可以实现代码复用,因为可能有很多相同的逻辑,知识参数不同而已,所以就没必要写类似的代码了,而是只需要加个参数就可以了。

下面我们实现一个案例,就是两个按钮控制窗口标题,使用同一个信号和槽:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 绑定自定义信号和槽函数connect(this, &Widget::set_window_title, this, &Widget::handle_set_window_title);
}
​
void Widget::handle_set_window_title(QString text)
{// 修i该窗口标题为 textthis->setWindowTitle(text);
}
​
// 通过 ui 界面生成的槽函数
void Widget::on_pushButton_clicked()
{// 设置窗口标题为1// 发射信号setWindowTitle("设置窗口标题为1");
}
​
void Widget::on_pushButton_2_clicked()
{// 设置窗口标题为2setWindowTitle("设置窗口标题为2");
}

信号槽断开绑定

如果当我们想要将一个信号绑定其他的槽函数我们应该怎么做呢? 我们是可以直接将该信号和其他的槽函数connect吗? 并不是,在 Qt 中一个信号可以绑定多个槽函数,而一个槽函数也可以被多个信号绑定,如果直接使用connect的话,那么就是将一个信号绑定了多个槽函数,所以需要先断开再去绑定其他的槽函数。

下面写一个案例,按钮按下后修改窗口标题,然后打印,按下下面的按钮则会切换一个槽函数绑定,另外一个槽函数也是修改窗口标题并打印

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 1. 先绑定 pushButton1 和 handle_clicked1connect(ui->pushButton, &QPushButton::clicked, this, &Widget::handle_clicked1);
}
​
void Widget::handle_clicked1()
{setWindowTitle("修改窗口标题1");qDebug() << "handle_clicked1";
}
​
void Widget::handle_clicked2()
{setWindowTitle("修改窗口标题2");qDebug() << "handle_clicked2";
}
​
// 将 pushButton 绑定的 handle_clicked1 切换为 handle_clicked2
void Widget::on_pushButton_2_clicked()
{// 1. 断开之前的链接disconnect(ui->pushButton, &QPushButton::clicked, this, &Widget::handle_clicked1);// 2. 重新链接connect(ui->pushButton, &QPushButton::clicked, this, &Widget::handle_clicked2);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/9234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET信息安全研究所设备管理系统的设计与实现

摘 要 以研究所的设备管理系统为背景&#xff0c;以研究所设备管理模式为研究对象&#xff0c;开发了设备管理系统。设备管理系统是设备管理与计算机技术相结合的产物&#xff0c;根据系统的功能需求分析与定义的数据模式&#xff0c;分析了应用程序的主要功能和系统实现的主…

zabbix动作执行命令失效不起作用?

1. zabbix在web界面设置完主机组&#xff0c;主机&#xff0c;监控项&#xff0c;触发器&#xff0c;动作之后 监控项监控到了&#xff0c;触发器触发动作&#xff0c;但是执行的指令不起作用 流程 在zabbix-agent端将nginx服务down掉&#xff0c;zabbix会自动监控并执行重启的…

TypeScript学习日志-第二十一天(声明文件d.ts)

声明文件d.ts 在使用 Typescript 并使用第三方库 的时候 我们会发现会有很多的提示或补全&#xff0c;这都是声明文件起的作用&#xff0c;但是有写冷门的第三方库是没有声明文件的&#xff0c;这时候引用就会报错&#xff0c;我们就使用 express 库作为例子来展示一下&#x…

CMake创建跨平台OPenGL工程(学习笔记)

一、跨平台环境基本配置 1、环境搭建 1&#xff09;linux OpenGL环境搭建参考&#xff1a;ubuntu18.04 OpenGL开发&#xff08;显示YUV&#xff09;_ubuntu opengl-CSDN博客 https://blog.51cto.com/cerana/6433535 2&#xff09;windows下环境搭建 OpenGLVisual Studio20…

【Linux系统】进程控制

再次理解进程 进程&#xff1a;内核的相关管理数据结构(task_struct(进程控制块PCB)&#xff0c;mm_struct(地址空间)&#xff0c;页表) 代码和数据 那么如何理解进程具有独立性&#xff1f; 我们之前已经学习过进程控制块啊&#xff0c;地址空间啊&#xff0c;页表啊&…

GitHub Actions 手动触发方式

目录 前言 Star Webhook 手动触发按钮 前言 GitHub Actions 是 Microsoft 收购 GitHub 后推荐的一款 CI/​CD 工具早期可能是处于初级开发阶段&#xff0c;它的功能非常原生&#xff0c;甚至没有直接提供一个手动触发按钮一般的触发方式为代码变动&#xff08;push 、pull…

【2024版】最新6款漏洞扫描工具来了!(附下载)看完这一篇就够了

目录 一、Nessus 二、AWVS 三、ZAP 四、w3af 五、北极熊 六、御剑 七、网络安全学习路线 &#xff08;2024最新整理&#xff09; 八、学习资料的推荐 1.视频教程 2.SRC技术文档&PDF书籍 3.大厂面试题 特别声明&#xff1a; 渗透测试收集信息完成后&#xf…

每日两题 / 104. 二叉树的最大深度 102. 二叉树的层序遍历(LeetCode热题100)

104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 递归判断&#xff0c;当前节点的最大深度为1 max(左节点的最大深度&#xff0c;右节点的最大深度) /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

Ansible---inventory 主机清单

一、inventory 主机清单 1.1、inventory介绍 hosts配置文件位置&#xff1a;/etc/ansible/hosts Inventory支持对主机进行分组&#xff0c;每个组内可以定义多个主机&#xff0c;每个主机都可以定义在任何一个或多个主机组内。 1.2、inventory中的变量 Inventory变量名含义…

八、VUE内置指令

一、初识VUE 二、再识VUE-MVVM 三、VUE数据代理 四、VUE事件处理 五、VUE计算属性 六、Vue监视属性 七、VUE过滤器 七、VUE内置指令 九、VUE组件 v-text 向其所在的节点中渲染文本内容。 (纯文本渲染)与插值语法的区别&#xff1a;v-text会替换掉节点中的内容&#xff0c;{{x…

springboot3项目练习详细步骤(第一部分:用户业务模块)

目录 环境准备 用户模块 注册 注册接口文档 ​编辑 实现结构 Spring Validation 登录 登录的接口文档 实现登录逻辑 JWT令牌 完善登录认证 拦截器 获取用户详细信息 接口文档 Usercontroller类中编写方法接口 忽略属性返回 优化代码ThreadLocal 更新用户基本信…

ubuntu启动修复(BIOS无法找到GRUB | 引导加载器)

Ubuntu启动修复&#xff08;无法找到GRUB|引导加载器&#xff09; 问题&#xff1a; 笔者的一台双系统主机&#xff0c;里面有两个硬盘&#xff0c;1T的硬盘装的是windows系统&#xff0c;2T硬盘装的是ubuntu20.04系统。因为长期使用ubuntu系统&#xff0c;所以选择格式化了1T…

Adobe Premiere Pro安装

一、安装包下载 链接&#xff1a;https://pan.baidu.com/s/1aYqTSQQutDguKYZE-yNHiw?pwd72l8 提取码&#xff1a;72l8 二、安装步骤 1.鼠标右击【Pr2024(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;【解压到 Pr2024(64bit)】。 2.打开…

【计算机毕设】小型企业办公自动化系统+vue - 免费源码(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个小型企业办公自动化系统&#xff0c;利用Vue作为前端框架&#xff0c;为企业员工提供便捷的办公管理工具&#xff0c;提升…

mysql数据库调优篇章1

目录 1.认识数据库中日志的作用2.增加mysql数据库中my.ini 基本配置3.增加my.ini中参数配置4.查看已经执行过的sql语句过去执行时间5.找出慢查询的sql6. SHOW VARIABLES LIKE ‘innodb_read_io_threads’; SHOW VARIABLES LIKE ‘innodb_write_io_threads’; SHOW VARIABLES LI…

ArthasGC日志GCeasy详解

Arthas详解 Arthas是阿里巴巴在2018年9月开源的Java诊断工具,支持JDK6,采用命令行交互模式,可以方便定位和诊断线上程序运行问题.Arthas官方文档十分详细.详见:官方文档 Arthas使用场景 Arthas使用 # github下载arthas wget https://alibaba.github.io/arthas/arthas-boot.j…

了解tensorflow.js

1、浏览器中进行机器学习的优势 浏览器中进行机器学习&#xff0c;相对比与服务器端来讲&#xff0c;将拥有以下四大优势&#xff1a; 不需要安装软件或驱动&#xff08;打开浏览器即可使用&#xff09;&#xff1b;可以通过浏览器进行更加方便的人机交互&#xff1b;可以通过…

智慧手术室手麻系统源码,C#手术麻醉临床信息系统源码,符合三级甲等医院评审要求

手麻系统全套源码&#xff0c;C#手术麻醉系统源码&#xff0c;支持二次开发&#xff0c;授权后可商用。 手术麻醉临床信息系统功能符合三级甲等医院评审要求&#xff0c;实现与医院现有信息系统如HIS、LIS、PACS、EMR等系统全面对接&#xff0c;全面覆盖从患者入院&#xff0c;…

前端css中径向渐变(radial-gradient)的使用

前端css中径向渐变的使用 一、前言二、主要内容说明&#xff08;一&#xff09;、径向渐变的形状1.椭圆形渐变&#xff08;ellipse&#xff09;&#xff0c;源码12.源码1运行效果3.圆形渐变&#xff08;circle&#xff09;&#xff0c;源码24.源码2运行效果 &#xff08;二&…

C++青少年简明教程:C++程序结构

C青少年简明教程&#xff1a;C程序结构 一个简单的C程序源码如下&#xff1a; #include <iostream> using namespace std;int main() {cout << "Hello World" << endl;return 0; }下面解析一下。 1. #include <iostream> 这行代码的意思…