Qt信号和槽-->day04

Qt信号和槽

  • 标准的信号和槽函数
    • Qt中的槽函数
    • Qt中的信号
  • connect
    • 案例
  • 自定义信号和槽
    • 案例分析
  • 信号槽的拓展
    • 信号连接信号案例
  • 信号槽的两种连接方式
    • Qt5中的处理方式
    • Qt4中的处理方式
    • Qt5处理信号槽重载问题
      • 案例
    • lambda表达式
      • 简单案例
      • Qt中的应用
  • 补充知识点

标准的信号和槽函数

QWidget标准的信号和槽函数
在这里插入图片描述
此外信号和槽函数是可以被继承的
在这里插入图片描述
可以看到QPushButton是有标准的槽函数,但是没有看到信号。
实际上QPushButton是继承了它的父类的信号
在这里插入图片描述

Qt中的槽函数

Qt中的槽函数可以是类的成员函数、全局函数、静态函数、Lambda表达式(匿名函数)

Qt中的信号

信号需要使用 signals 关键字进行声明, 使用方法类似于public等关键字

connect

connect(信号发生者,信号,信号接受者,接受者的处理动作);

connect只是做了一个信号注册,具体操作步骤是通过qt框架进行实现的

案例

功能实现: 点击窗口上的按钮, 关闭窗口
功能分析:
- 按钮: 信号发出者 -> QPushButton 类型
- 窗口: 信号的接收者和处理者 -> QWidget 类型
在这里插入图片描述

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
//  ui->closeBtn;//>>>>>>>>>>>>>>>>>>通过ui对象可以操纵所创建的按钮connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
}MainWindow::~MainWindow()
{delete ui;
}

不可以将第四个参数写为 &this->close,因为 &this->close 表示的是 MainWindow 类的成员函数指针,而 QPushButton::clicked 信号需要一个成员函数指针,而这个指针的类型是 void (MainWindow:😗)()(即没有参数且没有返回值的成员函数指针)。

自定义信号和槽

案例分析

假设要实现一个类GirlFriend发出hungry信号,一个类Me来接受信号进行处理。

  • 1、由于这两个是不同的类,所以应该提供一个窗口类对上面的这两个类进行包装
  • 2、在GirlFriend类中只需要声明信号,不需要实现,因为这是信号的发出者
  • 3、在Me类的槽函数不仅需要声明也需要实现

主窗口头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "girlfriend.h"
#include "me.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();public slots:void hungrySlot();private:Ui::MainWindow *ui;GirlFriend *g_girl;Me *m_me;
};
#endif // MAINWINDOW_H

主窗口函数实现

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
//  ui->closeBtn;//>>>>>>>>>>>>>>>>>>通过ui对象可以操纵所创建的按钮g_girl=new GirlFriend;m_me=new Me;//这个hungry是自定义的不由Qt框架提供,需要使用者发射信号 >>>>>>> 窗口中实现connect(g_girl,&GirlFriend::hungry,m_me,&Me::eat);//>>>>>>>>>>>>>>提醒Qt框架有信号connect(ui->hungry,&QPushButton::clicked,this,&MainWindow::hungrySlot);connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::hungrySlot()
{//发射信号emit g_girl->hungry();
}

在这里插入图片描述

信号槽的拓展

  • 一个信号可以连接多个槽函数, 发送一个信号有多个处理动作
    需要写多个connect()连接
    槽函数的执行顺序是随机的, 和connect函数的调用顺序没有关系
  • 信号的接收者可以是一个对象, 也可以是多个对象
    一个槽函数可以连接多个信号, 多个不同的信号, 处理动作是相同的
    需要写多个connect()连接
  • 信号可以连接信号
connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::siganl-new);
  • 信号槽可以断开信号 --> 很少使用
disconnect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);

信号连接信号案例

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
//  ui->closeBtn;//>>>>>>>>>>>>>>>>>>通过ui对象可以操纵所创建的按钮g_girl=new GirlFriend;m_me=new Me;//这个hungry是自定义的不由Qt框架提供connect(g_girl,&GirlFriend::hungry,m_me,&Me::eat);connect(g_girl,&GirlFriend::hungry,this,&MainWindow::eatSlot);//信号连接信号connect(ui->hungry,&QPushButton::clicked,g_girl,&GirlFriend::hungry);//信号连接槽函数//connect(ui->hungry,&QPushButton::clicked,this,&MainWindow::hungrySlot);connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::hungrySlot()
{//发射信号emit g_girl->hungry();
}void MainWindow::eatSlot()
{qDebug()<<"喝尿";
}

在这里插入图片描述

信号槽的两种连接方式

Qt5中的处理方式

第二个和第四个参数是函数地址
在这里插入图片描述

Qt4中的处理方式

信号槽函数通过宏SIGNAL和SLOT转换为字符串类型
在这里插入图片描述

Qt5处理信号槽重载问题

signals:void hungry();void hungry(QString msg);
public slots://槽函数void eat();void eat(QString msg);

解决方案1:使用Qt4的信号与槽的机制(慎用,编译器不会报错如果你写错了)

    //Qt4的信号与槽connect(g_girl,SIGNAL(hungry()),m_me,SLOT(eat()));connect(g_girl,SIGNAL(hungry(QString)),m_me,SLOT(eat(QString)));

解决方案2:使用函数指针进行指定

    void(GirlFriend::*girl1)()=&GirlFriend::hungry;void(GirlFriend::*girl2)(QString)=&GirlFriend::hungry;void(Me::*point)(QString)=&Me::eat;void(Me::*pointt)()=&Me::eat;connect(g_girl,girl1,m_me,pointt);connect(g_girl,girl2,m_me,point);// >>>>> Qt5connect(g_girl,girl2,this,&MainWindow::eatSlot);// >>>>>> 信号是带参的而槽函数是不带参的 >>>> 直接就是执行eatSlot

案例

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
//  ui->closeBtn;//>>>>>>>>>>>>>>>>>>通过ui对象可以操纵所创建的按钮g_girl=new GirlFriend;m_me=new Me;//这个hungry是自定义的不由Qt框架提供
// >>>>>>>>>>>>>> Qt5处理重载void(GirlFriend::*girl1)()=&GirlFriend::hungry;void(GirlFriend::*girl2)(QString)=&GirlFriend::hungry;void(Me::*point)(QString)=&Me::eat;void(Me::*pointt)()=&Me::eat;connect(g_girl,girl1,m_me,pointt);connect(g_girl,girl2,m_me,point);// >>>>> Qt5connect(g_girl,girl2,this,&MainWindow::eatSlot);
//err//connect(g_girl,&GirlFriend::hungry,m_me,&Me::eat);// >>>>> Qt5//connect(g_girl,&GirlFriend::hungry,this,&MainWindow::eatSlot);//Qt4的信号与槽connect(g_girl,SIGNAL(hungry()),m_me,SLOT(eat()));connect(g_girl,SIGNAL(hungry(QString)),m_me,SLOT(eat(QString)));//信号连接信号//connect(ui->hungry,&QPushButton::clicked,g_girl,&GirlFriend::hungry);//信号连接槽函数connect(ui->hungry,&QPushButton::clicked,this,&MainWindow::hungrySlot);connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::hungrySlot()
{//发射信号g_girl->hungry();g_girl->hungry("粑粑");
}void MainWindow::eatSlot()
{qDebug()<<"喝尿";
}

在这里插入图片描述
在这里插入图片描述

lambda表达式

lambda表达式–>匿名函数

[capture](params) opt -> ret {body;};- capture: 捕获列表- params: 参数列表- opt: 函数选项- ret: 返回值类型- body: 函数体
捕获列表: 捕获一定范围内的变量[] - 不捕捉任何变量[&] - 捕获外部作用域中所有变量, 并作为引用在函数体内使用 (按引用捕获)[=] - 捕获外部作用域中所有变量, 并作为副本在函数体内使用 (按值捕获)拷贝的副本在匿名函数体内部是只读的[=, &foo] - 按值捕获外部作用域中所有变量, 并按照引用捕获外部变量 foo[bar] - 按值捕获 bar 变量, 同时不捕获其他变量[&bar] - 按引用捕获 bar 变量, 同时不捕获其他变量[this] - 捕获当前类中的this指针让lambda表达式拥有和当前类成员函数同样的访问权限如果已经使用了 & 或者 =, 默认添加此选项

简单案例

// 匿名函数的定义, 程序执行这个匿名函数是不会被调用的
[](){qDebug() << "hello, 我是一个lambda表达式...";
};// 匿名函数的定义+调用:
int ret = [](int a) -> int
{return a+1;
}(100);  // 100是传递给匿名函数的参数

Qt中的应用

在这里插入图片描述

补充知识点

#include<iostream>
using namespace std;class a
{
public:void print(){cout << "1" << endl;}
};int main()
{a a;  // 创建对象a.print();// 声明成员函数指针并调用void (a:: * print_ptr)() = &a::print;  // 成员函数指针(a.*print_ptr)();  // 通过指针调用
}

在这里插入图片描述

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

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

相关文章

【超级详细】基于Zynq FPGA对雷龙SD NAND的测试

目录 一、SD NAND特征1.1 SD卡简介1.2 SD卡Block图 二、SD卡样片三、Zynq测试平台搭建3.1 测试流程3.2 SOC搭建 一、SD NAND特征 1.1 SD卡简介 雷龙的SD NAND有很多型号&#xff0c;在测试中使用的是CSNP4GCR01-AMW与CSNP32GCR01-AOW。芯片是基于NAND FLASH和 SD控制器实现的…

linux物理内存管理:node,zone,page

一、总览 对于物理内存内存&#xff0c;linux对内存的组织逻辑从上到下依次是&#xff1a;node&#xff0c;zone&#xff0c;page&#xff0c;这些page是根据buddy分配算法组织的&#xff0c;看下面两张图&#xff1a; 上面的概念做下简单的介绍&#xff1a; Node&#xff1a…

STM32-Flash闪存

目录 一、简介 1、闪存模块组织 2、FLASh基本结构 3、FLash写入和读取操作 4、编程流程 5、选项字节格式 6、选项字节编程步骤 二、读写芯片内部FLASH编程 三、器件电子签名 1、简介 2、编程实现 一、简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节…

数据结构之带头双向循环链表

前言&#xff1a;前面我们实现了顺序表和单链表&#xff0c;这次来实现一个结构更复杂的链表-----带头双向循环链表。不要被它的名字吓到哦&#xff0c;只是结构复杂而已&#xff0c;它的结构更有利于代码的实现。 1 双向循环链表的介绍 有了单链表的基础&#xff0c;要实现这…

10个最常用的Python包,程序员必备!

世界上有超过200,000个Python程序包&#xff08;这只是基于官方的Python程序包索引PyPI托管的程序包&#xff09;。 这就引出了一个问题&#xff1a;拥有这么多的软件包&#xff0c;每个Python程序员都需要学习哪些软件包是最重要的&#xff1f; 为了帮助回答这个问题&#x…

线上问题的排查-java死锁问题如何排查

这里写目录标题 1.java死锁如何排查2.具体步骤1.1识别死锁现象1.2收集线程转储1.3分析线程转储1.4代码审查1.5重现问题1.6使用调试工具1.7.优化和验证 3. 解决方案总结 1.java死锁如何排查 在Java应用程序中&#xff0c;死锁是一个经典的并发问题&#xff0c;它会导致线程永久阻…

shodan(4-5)

以下笔记学习来自B站泷羽Sec&#xff1a; B站泷羽Sec 1. 查看自己的出口IP 可以知晓自己是哪个IP连接的公网 shodan myip2. 指定标题搜索 http.title:内容搜索被挂黑页的网页&#xff1a;获得标题中含有hacked by的IP shodan search --limit 10 --fields ip_str,port htt…

三种风格截然不同的实验室工控界面

三种风格截然不同的实验室工控界面各具特色。一种可能是简洁现代风&#xff0c;以简洁的线条、纯净的色彩和直观的图标&#xff0c;呈现出高效与专业。 另一种或许是科技未来风&#xff0c;运用炫酷的光影效果和立体感十足的设计&#xff0c;展现实验室的前沿科技感。 还有一…

Redis如何保证数据不丢失(可靠性)

本文主要以学习为主&#xff0c;详细参考&#xff1a;微信公众平台 Redis 保证数据不丢失的主要手段有两个&#xff1a; 持久化 多机部署 我们分别来看它们两的具体实现细节。 1.Redis 持久化 持久化是指将数据从内存中存储到持久化存储介质中&#xff08;如硬盘&#xf…

STM32F405RGT6单片机原理图、PCB免费分享

大学时机创比赛时画的板子&#xff0c;比到一半因为疫情回家&#xff0c;无后续&#xff0c;&#xff0c;&#xff0c;已打板验证过&#xff0c;使用stm32f405rgt6做主控 下载文件资源如下 原理图文件 pcb文件 外壳模型文件 stm32f405例程 功能 以下功能全部验证通过 4路…

“穿梭于容器之间:C++ STL迭代器的艺术之旅”

引言&#xff1a; 迭代器&#xff08;Iterator&#xff09;是C STL&#xff08;标准模板库&#xff09;中非常重要的一部分&#xff0c;它提供了一种统一的方式来遍历容器中的元素。无论容器是数组、链表、树还是其他数据结构&#xff0c;迭代器都能够以一致的方式访问这些数据…

jmeter常用配置元件介绍总结之用linux服务器压测

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之用linux服务器压测 1.编写测试脚本2.执行测试脚本 1.编写测试脚本 在linux服务器上进行压测&#xff0c;由于是没有界面的&#xff0c;因此我们可以先在界面上把压测脚本写好&#xff1a; 如图&#xff1a;我这里简单的写…

Ubuntu 的 ROS 操作系统安装与测试

引言 机器人操作系统&#xff08;ROS, Robot Operating System&#xff09;是一个用于开发机器人应用的开源框架&#xff0c;它提供了一系列功能丰富的库和工具&#xff0c;能够帮助开发者构建和控制机器人。 当前&#xff0c;ROS1的最新版本为Noetic Ninjemys&#xff0c;专为…

计算机组成原理——编码与纠错(汉明编码)

校验码放在2^x次方的位置——即1&#xff0c;2&#xff0c;4——将检测位按序排列p3p2p1 汉明编码从左到右数某个位置位1&#xff08;位数&#xff09;&#xff0c;就表示第几组 奇偶校验 例题 纠错过程 汉明编码的最小距离是3

fabric操作canvas绘图(1)共32节

对于前端而言&#xff0c;离不开canvas就像鱼离不开水&#xff0c;前端canvas神器fabric你值得拥有&#xff01;接下来我们就来一步步揭开她的面纱。 一、fabric的理解 用原生的canvas来实现&#xff0c;代码量会比较大&#xff0c;而且还要处理很多细节&#xff0c;而Fabric…

C++ 内存分布及 new , delete 分配问题( ~~~ 面试重要 ~~~)

文章目录 前言一、内存分布二、new 、delete 分配问题总结 前言 本篇文章笔者将会对 C 中的内存问题简单的讲解 , 同时对 new , delete 的面试题进行重点讲解. 一、内存分布 ● C语言和C 分布情况是一样的, 如下 : ● 栈 ○ 栈 的管理是由编译器自动管理 , 不需要我们人为做…

数据结构-哈夫曼树

一.什么是哈夫曼树 不同搜索树的效率是不一样的,根据不同的频率构造效率比较好或者最好的搜索树就是哈夫曼树 二.哈夫曼树的定义 将带权路径的长度降低最低 每个叶子节点到根节点的距离乘权值&#xff0c;再全都加起来就得到了WPL值 第一颗二叉树:从上到下计算 5x14x23x32x41…

双11精选网络安全书单:打造数字世界的钢铁长城!

&#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 &#x1f31f;双11火热来袭&#xff0c;网络安全书单推荐&#x1f680; 随着数字化浪潮的汹涌澎湃&#xff0c;网络安全已经成为了每个从业者不可回避的重要议…

WebGUI之Gradio:Gradio 5的简介、安装和使用方法、案例应用之详细攻略

WebGUI之Gradio&#xff1a;Gradio 5的简介、安装和使用方法、案例应用之详细攻略 目录 Gradio 5的简介 1、Gradio的适用场景 2、Gradio 5 的主要改进包括&#xff1a; Gradio 5的安装和使用方法 1、安装和使用方法 2、使用方法 2.1、文本内容 (1)、简单的输入/输出组件…

初始Python篇(5)—— 集合

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 集合 相关概念 集合的创建与删除 集合的操作符 集合的相关操作方法 集合的遍历 集合生成式 列表、元组、字典、集合的…