信号槽机制

news2024/12/24 8:57:47

目录

信号槽机制

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. 创建一个 QpushButton
    QPushButton* 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该窗口标题为 text
    this->setWindowTitle(text);
}
​
// 通过 ui 界面生成的槽函数
void Widget::on_pushButton_clicked()
{
    // 设置窗口标题为1
    // 发射信号
    setWindowTitle("设置窗口标题为1");
}
​
void Widget::on_pushButton_2_clicked()
{
    // 设置窗口标题为2
    setWindowTitle("设置窗口标题为2");
}

信号槽断开绑定

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

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 1. 先绑定 pushButton1 和 handle_clicked1
    connect(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.coloradmin.cn/o/1658511.html

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

相关文章

百度地图API 快速入门

一、创建一个应用 创建成功可以在应用程序中查看到自己的ak密钥 二、基本使用 2.1 显示地图 在static下创建demo1.html &#xff08;将密钥换成自己的就可以显示地图了&#xff09; 示例&#xff1a; <!DOCTYPE html> <html> <head><meta name"…

HTML4(四)

1. 框架标签 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>框架标签</title></head><body><!-- 利用iframe嵌入一个普通网页 --><iframe src"https://www.toutia…

FPGA+MCU+SDRAM方案,用于服装厂生产过程中以及设计过程中制作样板,剪裁布料

FPGAMCUSDRAM方案&#xff0c;用于服装厂生产过程中以及设计过程中制作样板&#xff0c;剪裁布料 客户应用&#xff1a;服装厂制衣 主要功能&#xff1a; 1.支持步进电机、直流电机 2.支持同时3轴电机协调工作 3.支持以太网/USB联机控制 4.支持LCD 屏显示状态 5.支持HP11/…

AI大模型探索之路-训练篇18:大语言模型预训练-微调技术之Prompt Tuning

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

mysql安装及基础设置

关系型数据库 MySQL是一种关系型数据库管理系统&#xff0c;采用了关系模型来组织数据的数据库&#xff0c;关系数据库将数据保存在不同的表中&#xff0c;用户通过查询 sql 来检索数据库中的数据。 yum 方式安装 mysql # yum -y install mysql-server # systemctl start my…

2024 全自动ai生成视频MoneyPrinterTurbo源码

只需提供一个视频 主题 或 关键词 &#xff0c;就可以全自动生成视频文案、视频素材、视频字幕、视频背景音乐&#xff0c;然后合成一个高清的短视频。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89208288 更多资源下载&#xff1a;关注我。

OSI网络7层的功能介绍

目录 1.OSI功能介绍 2.SNA 3.X.25 1.OSI功能介绍 2.SNA SNA: IBM Systems Network Architecture)SNA是IBM公司开发的网络体系结构&#xff0c;在IBM公司的主机环境中得到广泛的应用。一般来说&#xff0c;SNA主要是IBM公司的大型机(ES/9000、S/390等)和中型机(AS/400)的主要…

SpringSecurity源码分析(RemeberMe)

RememberMeServices RememberMeServices 记住我的服务的接口 可以重写实现自己的记住我 public interface RememberMeServices { //建议 org. springframework. security. authentication. RememberMeAuthenticationToken 在大多数情况下使用它&#xff0c;因为它具有相应的身份…

物理层——计算机网络学习笔记二

目录 物理层的基本概念 数据通信的基础知识 物理层下面的传输媒体 信道复用技术 图片大部分来源于谢希仁《计算机网络》教材配套的ppt。 这一样都是介绍一下概念性的东西&#xff0c;了解一下就行&#xff0c;就重要性而言不如后面的内容。 物理层的作用&#xff1a;考虑如何才…

AlphaFold 3 可以预测所有生命分子的结构和相互作用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

酷企秀场景elementUi plus可视化diy

无论网络公司还是政务企业需求的所需的一单可回本的 独立部署集三大功能&#xff1a;电子画册、VR全景、地图秀等功能都可以可视化在线设计 后续免费增加 自定义表单、抽奖活动功能。 源码交付&#xff0c;独立私有化部署&#xff0c;无限多开&#xff0c;可视化设计&#x…

视频剪辑一键处理技巧:批量分割视频,快速提取m3u8视频

随着网络视频的普及和多样化&#xff0c;视频剪辑和处理成为了很多用户的基本需求。在众多的视频处理技巧中&#xff0c;批量分割视频快速提取m3u8视频是常见的操作。本文将介绍如何利用云炫AI智剪一键处理的技巧&#xff0c;轻松完成这些任务&#xff0c;提高视频剪辑的效率。…

Element ui input 限制只能输入数字,且只能有两位小数

<el-form-item label"整体进度&#xff1a;" prop"number"> <el-input v-model"formInline.number" input"handleInput" placeholder"百分比" clearable></el-input>% </el-form-item&g…

指针的奥秘(二):指针与数组的联系+字符指针+二级指针+指针数组+《剑指offer》笔试题

指针 一.指针与数组的联系1.数组名的理解2.使用指针访问数组3.一维数组传参的本质 二.字符指针1.字符指针隐藏秘密2.常量字符串3.《剑指offer》笔试题 三.二级指针四.指针数组1.指针数组模拟二维数组 一.指针与数组的联系 1.数组名的理解 也许大部分人认为数组名就是一个名称&…

前端基础知识-ES6扩展运算符(快速实现数组添加新元素、字符串转为数组、对象添加新属性)

前言&#xff1a; 扩展运算符又称为Rest运算符&#xff0c;可以实现数组、对象、字符串在语法层面上的展开&#xff0c;达到简化语法的目的&#xff0c;使得我们提高开发效率 主要用法&#xff1a; 在需要解构的变量前加三个点&#xff08;...xxx&#xff09; 具体示例&…

猿匹配,一款使用环信实现的一个开源聊天应用含服务器

前言 之前写了一篇Android开发集成聊天环信SDK3.x简单开始&#xff0c;然后最近得空开发了一款使用环信实现的实时聊天应用&#xff0c;包含简单的服务器端&#xff0c;并开源给大家&#xff0c;有兴趣的同学可以一起搞一下&#xff0c;详细介绍看下边吧 上代码 服务器&#…

89C52单片机+ESP8266做的物联网+反馈 e4a手机客户端源程序

资料下载地址&#xff1a;89C52单片机ESP8266做的物联网反馈 e4a手机客户端源程序 MCU是89C52单片机 WiFi模块是ESP8266 其他 8路继电器 电源模块 使用贝壳物联做服务器 还有客户端。 也可以用花生壳做内网穿透&#xff0c;8266做服务器&#xff0c;也可以实现物联以及反馈&a…

攻击者正在利用AI,对保险公司发起大规模欺诈

保险欺诈一直是保险行业面临的重要挑战之一&#xff0c;尤其随着技术的进步&#xff0c;欺诈者也在不断更新其手段&#xff0c;利用AI技术&#xff0c;包括生成式模型、机器学习和数据分析工具等欺骗保险公司&#xff0c;而AI技术的应用正成为他们的新工具&#xff0c;使其犯罪…

VSCode(安装)

前言 VSCode&#xff08;全称&#xff1a;Visual Studio Code&#xff09;是一款由微软开发且跨平台的免费源代码编辑器。该软件支持语法高亮、代码自动补全&#xff08;又称 IntelliSense&#xff09;、代码重构、查看定义功能&#xff0c;并且内置了命令行工具和 Git …

韩顺平0基础学Java——第7天

p110-p154 控制结构&#xff08;第四章&#xff09; 多分支 if-elseif-else import java.util.Scanner; public class day7{public static void main(String[] args) {Scanner myscanner new Scanner(System.in);System.out.println("input your score?");int s…