嵌入式QT (Qt 信号与槽)

news/2024/11/23 17:03:13/

一、Qt 信号与槽机制

因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。

信号(Signal)就是在特定情况下被发射的事件。
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:

connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

sender 是发射信号的对象的名称,signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。receiver 是接收信号的对象名称,slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数。

关于信号与槽的使用,有以下一些规则需要注意:
一个信号可以连接多个槽,例如:

connect(pushButton, SIGNAL(clicked()), this, SLOT(hide());
connect(pushButton, SIGNAL(clicked()), this, SLOT(close());

这是当一个对象 pushButton 的被单击时,所在窗体有两个槽进行响应,一个 hide()用于隐藏主窗体,一个 close 用于关闭主窗体。

多个信号可以连接同一个槽,如下:

connect(pushButton,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_2,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_3,SIGNAL(clicked()),this,SLOT(close()));

这样,当任何一个 pushButton 被单击时,都会执行 close()函数,进而关闭或者退出程序。

一个信号可以连接另外一个信号(说明了 connect 万物皆可连,非常好用!),例如:

connect(pushButton, SIGNAL(objectNameChanged(QString)),this, SIGNAL(windowTitelChanged(QString)));

这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。

在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT(特别重要)。

当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。

总结如下图,可以看到发送者与发送的信号是在一起的,接收者与接收的信号/槽是在一起的。它们不能在 connect()方法里写乱顺序!由发送者发送出信号到接收者用信号/槽接收。
在这里插入图片描述
disconnect(),这个方法重载了好几个函数,解开格式如
下。

bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)

1、断开一切与 myObject 连接的信号或槽。

disconnect(myObject, 0, 0, 0);

相当于非静态重载函数:

myObject->disconnect();

2、断开所有连接到特定信号的东西。

disconnect(myObject, SIGNAL(mySignal()), 0, 0);

相当于非静态重载函数:

myObject->disconnect(SIGNAL(mySignal()));

3、与指定的接收者断开连接。

disconnect(myObject, 0, myReceiver, 0);

相当于非静态重载函数:

myObject->disconnect(myReceiver);

二、 如何在项目里创建信号

由于信号只需声明,无需定义。所以我们只需要在 mianwindow.h 里声明信号即可。代码如下,如下图黑色加粗部分代码就是创建的信号。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
/* 引入 QPushButton */
#include <QPushButton>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:/* 声明一个信号,只需声明,无需定义 */void pushButtonTextChanged();};
#endif // MAINWINDOW_H

三、如何在项目中创建槽

创建槽的方法也很简单,也是直接在 mianwindow.h 里直接声明槽,在 mianwindow.cpp 里实现槽的定义,声明槽必须写槽的定义(定义指函数体的实现),否则编译器编译时将会报错。

槽有以下特点:

  1. 槽可以是任何成员函数、普通全局函数、静态函数
  2. 槽函数和信号的参数和返回值要一致

根据上面的槽特点,由于我们在第二小节里声明了信号void pushButtonTextChanged();所以我们声明的槽函数必须是无返回值类型void,和无需参数。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
/* 引入 QPushButton */
#include <QPushButton>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:/* 声明一个信号,只需声明,无需定义 */void pushButtonTextChanged();public slots:/* 声明一个槽函数 */void changeButtonText();/* 声明按钮点击的槽函数 */void pushButtonClicked();private:/* 声明一个对象 pushButton */QPushButton *pushButton;
};
#endif // MAINWINDOW_H

在 mainwindow.cpp 里实现 声 明 的 槽 函 数 void changeButtonText();voidpushButtonClicked();。同时还实例化了 pushButton 对象。代码如下。

#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{/* 设置窗体的宽为 800,高为 480 */this->resize(800,480);/* 实例化 pushButton 对象 */pushButton = new QPushButton(this);/* 调用 setText()方法设定按钮的文本 */pushButton->setText("我是一个按钮");
}MainWindow::~MainWindow()
{}/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{/* 使用 emit 发送信号 */emit pushButtonTextChanged();
}/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{/* 在槽函数里改变按钮的文本 */pushButton->setText("被点击了!");
}

四、 如何在项目中连接信号与槽

信号槽连接的代码如下。

connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));
connect(this, SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText()));

注意,发送信号的对象,和接收的信号的对象。因为我们 pushButtonClicked()是本类里定义的槽,所以用 this 来接收。同理,pushButtonTextChanged()也是本类定义的信号。所以发送者写成 this。changeButtonText()也是本类的槽函数,所以接收槽的对象也是 this。

在 mainwindow.cpp 中信号槽连接的代码如下。

#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{/* 设置窗体的宽为 800,高为 480 */this->resize(800,480);/* 实例化 pushButton 对象 */pushButton = new QPushButton(this);/* 调用 setText()方法设定按钮的文本 */pushButton->setText("我是一个按钮");/* 信号与槽连接 */connect(pushButton, SIGNAL(clicked()), this,SLOT(pushButtonClicked()));connect(this, SIGNAL(pushButtonTextChanged()), this,SLOT(changeButtonText()));
}MainWindow::~MainWindow()
{}/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{/* 使用 emit 发送信号 */emit pushButtonTextChanged();
}/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{/* 在槽函数里改变按钮的文本 */pushButton->setText("被点击了!");
}

整个流程就是当点击了按钮,然后触发了 pushButtonClicked()pushButtonClicked()槽里发送 pushButtonTextChanged()信号,changeButtonText()槽响应 pushButtonTextChanged()信号,我们在 changeButtonText()槽实现响应的动作(事件)。最终的实现效果是按钮的文本由“我是一个按钮”被点击时变成“被点击了!”。

五、学会使用 Qt 类的信号与槽

要想使用 Qt 的信号与槽,那么我们必须知道有哪些信号与槽。在 第四节的代码里。

connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));

如下图示,按住 Ctrl 键,再点击 clicked(),进入 clicked()这个信号的定义处。
在这里插入图片描述
进入 QPushButton 的定义处,我们看到 QPushButton 不止 clicked 信号,还有其他信号,也有 QPushButton 的槽函数(返回上一步按 Alt + 方向左键)。在这里我们只是简单的看了如何在已知信号和槽里查找其他信号与槽。实际上在开发中我们经常需要使用 Qt 帮助文档来查看 Qt定义的信号与槽。
在这里插入图片描述


http://www.ppmy.cn/news/53775.html

相关文章

Spring Security 6.0系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 本系列Spring Authorization Server 版本 1.0.2 源码地址&#xff1a;https://gitee.com/pearl-organization/study-spring-securit…

肝一肝设计模式【二】-- 工厂模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 文章目录 系列文章目录前言一、简单工厂模式二、工厂方法模式三、抽象工厂模式写在最后 前言 在实际开发过程中&#xff0c;构建对象往往使用new的方式来构建&#xff0c;但随着…

​UWA报告使用技巧小视频,你get了么?(第十弹)

本期UWA报告使用小技巧将分享“回归测试”、“CPU压力较大”、“内存压力较大”这三种不同场景下&#xff0c;使用GOT Online测试时UWA推荐的参数开关配置。项目组可以根据问题排查的需求&#xff0c;自定义相应模块的开关&#xff0c;以便实现在尽可能不干扰你想获得的数据类型…

【VM服务管家】VM4.0平台SDK_2.4 结果获取类

目录 2.4.1 数据结果&#xff1a;通过流程输出或模块输出获取数据结果的方法2.4.2 流程运行&#xff1a;所有流程运行结束的回调方法2.4.3 模块回调&#xff1a;所有模块运行结束的回调方法2.4.4 加密狗回调&#xff1a;获取加密狗状态的回调方法2.4.5 方案加载&#xff1a;方案…

【Hadoop-HDFS】HDFS中Fsimage与Edits详解

【Hadoop-HDFS】HDFS中Fsimage与Edits详解 1&#xff09;概述2&#xff09;NameNode元数据解析3&#xff09;Fsimage3.1.Fsimage 的作用3.2.FSimage 的文件信息查看 4&#xff09;Edits4.1.Edits 的作用4.2.Edits 的文件信息查看 5&#xff09;元数据信息目录的配置 1&#xff…

报告打印的相关CAPL函数,实例代码演示汇总

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 目录 📙1 测试用例中报告打印相关1.1 TestCaseTitle1.2 TestCaseDescripti…

PAt A1015 Reversible Primes

1015 Reversible Primes 分数 20 作者 CHEN, Yue 单位 浙江大学 A reversible prime in any number system is a prime whose "reverse" in that number system is also a prime. For example in the decimal system 73 is a reversible prime because its rever…

C# WebService的开发以及客户端调用

目录 1、WebService简介 1.1 什么是XML&#xff1f; 1.2 什么是Soap&#xff1f; 1.3 什么是WSDL&#xff1f; 2、WebService与WebApi的区别与优缺点 2.1 WebService与WebApi的区别&#xff1a; 2.2 WebService的优缺点&#xff1a; 2.3 WebApi的优缺点&#xff1a; 3…