QT的核心——信号与槽

目录

回顾C 语言信号

1、信号与槽

2、关联信号与槽

2.1自动关联信号与槽

2.2手动关联信号与槽

2.3断开信号与槽

3、自定义信号

3.1自定义信号使用条件

3.2自定义槽函数使用条件

4、信号与槽参数传递

4.1自定义一个带参的信号

4.2关联带参的信号与槽

4.3发送一个带参的信号

5、信号与槽的相互关联

6、lambda表达式

 lambda 表达式的应用

 7、lambda 与 信号和槽


回顾C 语言信号

signal(设置信号处理方式)功能:注册一个信号处理函数,当收到该信号后,就会触发handler 函数表头文件 #include<signal.h>定义函数 void *signal(int signum,void(* handler)(int));signum : 需要捕捉的信号。handler : 收到信号后执行的函数

1.捕捉的信号能自定义吗? 不可以,只能使用系统预定义好的信号

2.信号可以传输数据吗? 不可以,信号只负责通知

所以QT 在 C 语言的信号基础进行封装,把上述两个问题都解决了。 在QT 中用户可以自定义信号, 在QT 中用户可以通过信号与槽传递参数。

信号:各种事件

槽: 响应信号的动作

1、信号与槽

当某个事件发生后,如某个按钮被点击了一下,它就会发出一个被点击的信号(signal)。

某个对象接收到这个信号之后,就会做一些相关的处理动作(称为槽slot)。

但是Qt对象不会无故收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)

//QT的四个信号

  1. pressed():鼠标按下时触发。对应的函数是 mousePressEvent()。
  2. clicked():鼠标松开时触发。如果鼠标拖拽到按钮区域之外释放则不会触发。对应的函数是 mouseReleaseEvent()。一般情况下 connect 槽函数时使用该信号。
  3. released():鼠标松开时触发。即使鼠标拖拽到按钮区域之外释放也会触发。对应的函数是 mouseReleaseEvent()。
  4. toggled():设置 setCheckable(true) 后再单击按钮才会触发该信号。一般用于多个按钮组成 QButtonGroup 并且 setExclusive(true) 设置按钮间互斥。 正常情况下单击按钮,响应顺序为:pressed() — about 215ms — released() — almost 0ms — clicked()。

2、关联信号与槽

关联的方法有两种:自动关联,手动关联。下面对此进行一次次介绍

2.1自动关联信号与槽

在项目 增加信号和槽的方法一:在UI设计师中增加

第一步:右击控件,在弹出的对话框,

在下拉列表中,选择"转到槽",会弹出选择对话框

第二步:选择自己信号

会自动生成槽函数(.h和.cpp)

第三步:当点击相应的控件时,对应的槽函数就会被调用,从面是实现动态交互的效果

槽函数

2.2手动关联信号与槽

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 表示槽函数名,type 表示连接类型

type参数的值

描述

解释

Qt::DirectConnection

直接连接

即在信号发出时直接调用槽函数,槽函数会立即执行,而不管当前的线程是否与信号发出者在同一个线程

Qt::QueuedConnection

排队连接

将信号事件放入接收对象的事件队列中,槽函数会在事件循环处理时被执行,适用于跨线程的连接

Qt::BlockingQueuedConnection

阻塞排队连接

槽函数会在接收对象的线程中执行,并且当前线程会阻塞,直到槽函数执行完成

Qt::AutoConnection

自动连接

如果信号发送者和接收者在同一个线程,使用直接连接,否则使用排队连接

Qt::UniqueConnection

唯一连接

已经存在相同的连接,则不会创建新的连接,可以避免重复连接导致的问题,如重复执行槽函数等

 在QT4和QT5中,手动关联有着意义重大的调整,QT4不会检查信号与槽的参数是否匹配,而QT5会自动检查信号与槽的参数是否匹配。

下面给出QT4和QT5的关联例子:

QT4:

 //手动关联信号与槽        this 表示的是当前窗体,MainWindow
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));

QT5:

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

2.3断开信号与槽

语法:

语法: QT4: disconnect(信号发送者地址,SIGNAL(信号名(参数列表)),信号接收者地址,SLOT(槽名称(参数列表)));

QT5: disconnect(信号发送者地址,&发送者类名::信号名,信号接收者地址,&接受者类名::槽名称);

void MainWindow::on_pushButton_2_clicked()
{//取消信号与槽的关联 QT4// disconnect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));//取消信号与槽的关联 QT5disconnect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::on_pushButton_clicked);//因为自动关联,QT软件采用的是QT4的语法关联,所以取消只能用QT4 。//关联时使用了那种方法,取消时要一致!!qDebug() << "取消关联";
}

注意:使用自动关联的时候,QT软件采用的是QT4的语法关联,所以取消关联只能用QT4;使用手动关联的时候,关联时使用了那种方法,取消时要一致

3、自定义信号

在QT中,信号是可以自定义的,语法如下:

//在xxx.h头文件中 声明信号 
signals:  void 信号名(参数列表); 

注意:信号只需要声明不需要定义!!!

 但是可以看到定义信号的时候可以参数,参数的类型在信号定义的时候必须已经确定,而且不能改变,信号默认只能传递基本的类型如下(列举部分):

int:整数类型

double:双精度浮点数类型

QString:字符串类型

QDate:日期类型

QTime:时间类型

QColor:颜色类型

在C++中,参数支持默认参数,那么在QT的信号定义时,当然也可以为参数设置默认值

定义完自定义信号之后,需要代码来控制发送信号,发送语法如下:

//使用  emit 信号名(参数列表); 发送信号  
emit  mysig(); //发送一个mysig信号 

在发出信号时,如果没有指定参数,则使用默认值。

自定义信号与槽的关联和上面的关联是类似的:

 //信号在那个类中定义的,该类就是发送者connect(this,SIGNAL(mysig()),this,SLOT(getsig()));//发送信号emit  mysig();//温馨提示:信号的发送必须在"关联后"发送,否则该信号失效 

3.1自定义信号使用条件

  1. 声明在类的signals域下
  2. 没有返回值,void类型的函数
  3. 只有函数声明,没有定义
  4. 可以有参数,可以重载
  5. 通过emit关键字来触发信号,形式:emit object->sig(参数);

3.2自定义槽函数使用条件

  1. qt4 必须声明在 private/public/protected slots域下面,qt5之后可以声明public下,同时还可以是静态的成员函数,全局函数,lambda表达式
  2. 没有返回值,void类型的函数
  3. 不仅有声明,还得要有实现
  4. 可以有参数,可以重载

4、信号与槽参数传递

4.1自定义一个带参的信号

#ifndef MAINWINDOW_H
#define MAINWINDOW_Hclass MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();//自定义一个带参的信号
signals:void mysig(int a);//注意:信号与槽的参数类型必须匹配!! 
//声明一个带参的槽函数
public  slots: void getsig(int a);  private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

4.2关联带参的信号与槽

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//关联带参的信号与槽,信号与槽的参数都需要在关联是列举出来 connect(this,SIGNAL(mysig(int)),this,SLOT(getsig(int)));
}MainWindow::~MainWindow()
{delete ui;
}

4.3发送一个带参的信号

emit  mysig(10010); 

 注意事项:

  1. 信号参数的类型必须要与槽函数的类型匹配 参数类型不匹配会发生报错: MainWindow::mysig(QString) --> MainWindow::myslot(int)
  2. 信号参数的个数必须大于槽函数参数的个数(理解:能少接受发来的信号,不能多接受发来的信号) 槽参数的个数大于信号参数个数 : MainWindow::mysig(int) --> MainWindow::myslot(int,int,int)

5、信号与槽的相互关联

6、lambda表达式

  1. capture 子句(在 C++ 规范中也称为 Lambda 引导。)
  2. 参数列表(可选)。 (也称为 Lambda 声明符)
  3. mutable 规范(可选)。
  4. 异常规范(可选)。
  5. 后面的-返回值-类型(可选)。
  6. Lambda 体。
语法:
auto func = [capture] (params) opt -> ret { func_body; };func是可以当作lambda表达式的名字,作为一个函数使用
capture是捕获列表
params是参数表
opt是函数选项(mutable之类)
ret是返回值类型
func_body是函数体。  capture是捕获列表:
[]不捕获任何变量
[&]引用捕获,捕获外部作用域所有变量,在函数体内当作引用使用,可以修改值
[=]值捕获,捕获外部作用域所有变量,在函数内内有个副本使用  ,不可以修改值
[=, &a]值捕获外部作用域所有变量,按引用捕获a变量
[a]只值捕获a变量,不捕获其它变量
[this]捕获当前类中的this指针opt选择:
int a = 0;
auto f1 = [=](){ return a; }; // 值捕获a
cout << f1() << endl;
auto f2 = [=]() { return a++; }; // 修改按值捕获的外部变量,error
auto f3 = [=]() mutable { return a++; }; //添加mutable 选项可以修改

 lambda 表达式的应用

#include <iostream>
#include <list>
using  namespace std;int main() {list<int> vec;vec.push_back(10);vec.push_back(45);vec.push_back(4);vec.push_back(48);vec.sort(); for(int i:vec){cout << i << endl;}//自定义排序的规则 vec.sort([](int a,int b){return a>b;});for(int i:vec){cout << i << endl;}
}

基础写法

 数据捕获问题

 7、lambda 与 信号和槽

QT 中的一些简单功能的槽函数可以直接设计为 lambda 表达式,这样就不用在头文件声明槽,在源文件定义槽。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{ui->setupUi(this);//手动关联信号与槽 , 去头文件声明 myslot  ,再定义 myslot  很麻烦//connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::myslot);//把槽函数修改为 lambda表达式connect(ui->pushButton,&QPushButton::clicked,this,[](){qDebug() << "按钮点击";});}

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

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

相关文章

YOLOv5、YOLOv8改进:S2注意力机制

目录 1.简介 2.YOLOv5改进 2.1增加以下S2-MLPv2.yaml文件 2.2common.py配置 2.3yolo.py配置 1.简介 S2-MLPv2注意力机制 最近&#xff0c;出现了基于 MLP 的视觉主干。与 CNN 和视觉Transformer相比&#xff0c;基于 MLP 的视觉架构具有较少的归纳偏差&#xff0c;在图像识…

LVS-DR+keepalived实现高可用负载群集

VRRP 通信原理&#xff1a; VRRP就是虚拟路由冗余协议&#xff0c;它的出现就是为了解决静态路由的单点故障。 VRRP是通过一种竞选的一种协议机制&#xff0c;来将路由交给某台VRRP路由。 VRRP用IP多播的方式&#xff08;多播地址224.0.0.18&#xff09;来实现高可用的通信&…

基于STM32+OneNet设计的物联网智慧路灯

一、前言 近年来&#xff0c;构筑智慧城市、推动城镇发展被国家列入重要工作范畴。发布的《超级智慧城市报告》显示&#xff0c;全球已启动或在建的智慧城市有1000多个&#xff0c;中国在建500个&#xff0c;远超排名第二的欧洲&#xff08;90个&#xff09;。从在建智慧城市的…

Android oaid

官方GitHub地址 https://github.com/gzu-liyujiang/Android_CN_OAID 生成和用途介绍 https://www.jianshu.com/p/1c7ef27d6db4 图片来源于上述网站 其他关于id的介绍 https://www.cnblogs.com/chenKnowledgeConllection/p/17380960.html https://zhuanlan.zhihu.com/p/55…

微信小程序拉起支付报: 调用支付JSAPI缺少参数: total_fee

1. 调用支付JSAPI缺少参数: total_fee 2. 检查返回给前端调起支付的参数是否正确 一开始是params.put("package", prepay_id); 回来改回params.put("package", "prepay_id"prepay_id);

leetcode 415.字符串相加

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/add-strings/description/ ps&#xff1a; 从两个字符串的末尾开始遍历&#xff0c;依次相加&#xff0c;若大于等于 10 则使用一个变量记录进位&#xff0c;遍历的时候若两个字符串其中一…

ASR(自动语音识别)任务中的LLM(大语言模型)

一、LLM大语言模型的特点 二、大语言模型在ASR任务中的应用 浅度融合 浅层融合指的是LLM本身并没有和音频信息进行直接计算。其仅对ASR模型输出的文本结果进行重打分或者质量评估。 深度融合 LLM与ASR模型进行深度结合&#xff0c;统一语音和文本的编码空间或者直接利用ASR…

OKCC在系统安全方面做了哪些措施?

语音通信行业&#xff0c;运营者普遍比较关心的问题是&#xff0c;运营风险如何控制&#xff1f;运营安全如何保证&#xff1f;OKCC呼叫中心又有那些风控措施来保证运营安全。 当前阶段&#xff0c;语音通信运营&#xff0c;最主要的风险主要包括以下几个方面&#xff1a; 一、…

无涯教程-Perl - wait函数

描述 该函数等待子进程终止,返回已故进程的进程ID。进程的退出状态包含在$?中。 语法 以下是此函数的简单语法- wait返回值 如果没有子进程,则此函数返回-1,否则将显示已故进程的进程ID Perl 中的 wait函数 - 无涯教程网无涯教程网提供描述该函数等待子进程终止,返回已故…

Three.js 实现模型材质局部辉光效果和解决辉光影响场景背景图显示的问题

1.Three.js 实现模型材质局部辉光效果 2.解决辉光效果影响场景背景图显示的问题 相关API的使用&#xff1a; 1. EffectComposer&#xff08;渲染后处理的通用框架&#xff0c;用于将多个渲染通道&#xff08;pass&#xff09;组合在一起创建特定的视觉效果&#xff09; 2. …

Java-运算符和控制语句(上)(基于c语言的补充)

算术运算符 关于求余 不管分子&#xff0c;分母是正还是负&#xff0c;对于分母&#xff0c;直接取正&#xff1b;对于分子若有负号&#xff0c;则先提取出来&#xff1b;剩下两个正的分子分母运算&#xff1b;最后&#xff0c;若刚才的分子有负号&#xff0c;对最后的结果添加…

Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计tbms

​ 项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以…

scala中json4s 使用详解

预备知识 json4s的数据结构AST (Abstract Syntax Tree)。 sealed abstract class JValue case object JNothing extends JValue // zero for JValue case object JNull extends JValue case class JString(s: String) extends JValue case class JDouble(num: Double) extend…

数字化时代,数据仓库和商业智能BI系统演进的五个阶段

数字化在逐渐成熟的同时&#xff0c;社会上也对数字化的性质有了进一步认识。当下&#xff0c;数字化除了前边提到的将复杂的信息、知识转化为可以度量的数字、数据&#xff0c;在将其转化为二进制代码&#xff0c;引入计算机内部&#xff0c;建立数据模型&#xff0c;统一进行…

CAS 一些隐藏的知识,您了解吗

目录 ConcurrentHashMap 一定是线程安全的吗 CAS 机制的注意事项 使用java 并行流 &#xff0c;您要留意了 ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 内部使用的是数组加链表加红黑树的结构&#xff0c;通过CASvolatile或synchronized的方式来保证线程安全的,这些原理…

TikTok或将于8月底关闭半闭环、速卖通或将推出“半托管”模式

《出海周报》是运营坛为外贸企业主和外贸人独家打造的重要资讯栏目&#xff0c;聚焦企业出海、海外市场动态、海外监管政策等方面&#xff0c;以简捷的方式&#xff0c;提升读者获取资讯的效率。 接下来运营坛为大家带来第15期出海周报&#xff0c;快来看看这周国内外市场发生了…

C++--红黑树

1.什么是红黑树 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出俩倍&#xff0c;因…

【Unity细节】Unity中的层级LayerMask

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

Mybatis Plus中使用LambdaQueryWrapper进行分页以及模糊查询对比传统XML方式进行分页

传统的XML分页以及模糊查询操作 传统的XML方式只能使用limit以及offset进行分页&#xff0c;通过判断name和bindState是否为空&#xff0c;不为空则拼接条件。 List<SanitationCompanyStaff> getSanitationStaffInfo(Param("name") String name,Param("bi…

前端---需要了解浏览器相关知识--浏览器请求服务器资源---缓存

知识点1: 掘金1&#xff1a;浏览器缓存 掘金2 :浏览器缓存 一、浏览器缓存 请求&#xff08;静态资源 &#xff5c; 动态资源&#xff09; 一、缓存是什么&#xff1f; 如果没有缓存的机制 每次都要重新请求静态资源 1.从网络上的下载时间&#xff0c;肯定大于从硬盘里读的…