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_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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);// >>>>> Qt5
    connect(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);// >>>>> Qt5
    connect(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)();  // 通过指针调用
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十大经典排序算法-冒泡算法详解介绍

1、十大经典排序算法 排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要…

ASMR助眠声音视频素材去哪找 吃播助眠素材网站分享

在快节奏的现代生活中&#xff0c;越来越多的人感到压力山大&#xff0c;许多人开始寻求助眠和放松的方式。而ASMR&#xff08;自发性知觉经络反应&#xff09;助眠声音视频&#xff0c;凭借其独特的声音刺激和放松效果&#xff0c;成为了睡前的“神器”。如果你是一位内容创作…

【Linux】常用命令(2.6万字汇总)

文章目录 Linux常用命令汇总1. 基础知识1.1. Linux系统命令行的含义1.2. 命令的组成 2. 基础知识2.1. 关闭系统2.2. 关闭重启2.3. 帮助命令&#xff08;help&#xff09;2.4. 命令说明书&#xff08;man&#xff09;2.5. 切换用户&#xff08;su&#xff09;2.6.历史指令 3.目录…

量化分析工具日常操作日记-5-通合科技

使用量化分析微信小程序工具“梦想兔企业智能风险分析助手”日常操作日记-5-军工-通合科技&#xff08;300491&#xff09;。 周末国家新政策&#xff0c;要大力支持军工行业&#xff0c;我用工具挖掘了两个低位股&#xff0c;供大家参考。通合科技&#xff08;300491&#xff…

4D施工奇迹:废弃码头变身地标体育场

SYNCHRO 促进协同和战略性施工&#xff0c;完成大型项目交付 改造举世闻名的海滨城市 为了提升球迷的比赛日体验&#xff0c;英国足球俱乐部埃弗顿足球俱乐部正在利物浦默西河畔废弃的布拉姆利摩尔码头建造一座新的现代化体育场。该体育场是利物浦城市总体规划的一部分&#xf…

图神经网络(GNN)入门笔记(1)——图信号处理与图傅里叶变换

一、信号处理&#xff1a;时域与频域 时域&#xff08;Time Domain&#xff09;是我们生活中常见的信号表示方式&#xff0c;以横轴为时间&#xff0c;纵轴为信号该时刻的强度&#xff08;幅度&#xff09;&#xff0c;就可以得到一张时域图。打个比方&#xff0c;通过每时每刻…

【八百客CRM-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【AIGC】如何在ChatGPT中制作个性化GPTs应用详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;前言&#x1f4af;什么是GPTsGPTs的工作原理GPTs的优势GPTs的应用前景总结 &#x1f4af;创建GPTS应用的基本流程进入GPTs创建界面方式一&#xff1a;按照引导完成生成创建GPTs方式二…

读书笔记--Java与线程

并发不一定要依赖多线程&#xff08;如PHP中很常见的多线程并发&#xff09;&#xff0c;但是Java里面谈论并发&#xff0c;大多数都与线程脱不了关系。 线程的实现 我们都知道&#xff0c;线程是比进程更轻量级的调度执行单位&#xff0c;线程的引入&#xff0c;可以把一个进程…

PICO+Unity 用手柄点击UI界面

如果UI要跟随头显&#xff0c;可将Canvas放置到XR Origin->Camera Offset->Main Camera下 1.Canvas添加TrackedDeviceGraphicRaycaster组件 2.EventSystem移动默认的Standard Input Module&#xff0c;添加XRUIInputModule组件 3.&#xff08;可选&#xff09;设置射线可…

三十六、Python基础语法(JSON操作)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种基于文本&#xff0c;轻量级的数据交换格式。它易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;在自动化测试中经常用来存放测试数据。 JSON的特点&#xff1a; 基于文本&#xff0c;不包含图…

产品设计理念:10个案例分享

在互联网时代&#xff0c;企业通过在线产品为用户提供服务。要在众多竞争产品中脱颖而出并吸引更多用户&#xff0c;企业不仅要提供优质的服务&#xff0c;还要在产品设计上给用户带来卓越的体验。互联网产品设计包括页面布局、服务内容、流程逻辑、色彩搭配、图标、按钮等多个…

智能社区服务小程序+ssm

智能社区服务小程序 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了智能社区服务小程序的开发全过程。通过分析智能社区服务小程序管理的不足&#xff0c;创建了一个计算机管理智能社区服务小程序的方案。文…

Flutter3.22.2中SliverAppBar设置背景色滑动显示颜色错误

在使用Flutter项目开发中&#xff0c;可能会有页面需要滑动收起标题栏的效果&#xff0c;一般都会使用SliverAppBar来实现&#xff0c;当项目的Flutter的SDK版本升级到3.4后&#xff0c;发现使用了SliverAppBar的页面&#xff0c;在滑动过程中&#xff0c;标题栏和状态栏的颜色…

Odoo | 免费开源ERP:汽车及零配件行业信息化解决方案

文 / 开源智造 Odoo亚太金牌服务 概述 围绕汽车行业产业链上下游企业的整体业务主线&#xff0c;提供面向汽车主机厂整车个性化制造解决方案&#xff0c;产业链上下游一体化协同解决方案&#xff0c;数字化精益制造解决方案、全价值链质量管理解决方案&#xff0c;数字化运营解…

目前对于后期的打算

在完成了 Python 基本语法的学习后&#xff0c;我犹如推开了编程世界的一扇大门&#xff0c;初窥门径却也深知前方还有广袤无垠的知识天地等待我去探索。Python 作为一门广泛应用于软件开发、数据分析和人工智能等领域的高级编程语言&#xff0c;在当今数字化时代具有举足轻重的…

React中右击出现自定弹窗

前言 在react中点击右键,完成阻止浏览器的默认行为,完成自定义的悬浮框(Menu菜单). 版本 "react": "^18.2.0", "umijs/route-utils": "^4.0.1", "antd": "^5.18.1", "ant-design/pro-components": &q…

Elasticsearch如果集群出现节点故障,我应该如何快速定位问题?

当 Elasticsearch (ES) 集群发生故障时&#xff0c;快速定位问题源头非常重要。Elasticsearch 是一个分布式系统&#xff0c;故障可能由多种原因引起&#xff0c;涉及到硬件、配置、网络、集群本身的健康状况等多个层面。以下是一些定位问题的步骤和工具&#xff1a; 检查集群…

【Docker】Docker基础及docker-compose

一、Docker下载 更新yum包 yum update 安装需要的软件包&#xff08; yum-util 提供yum-config-manager功能&#xff0c;后两个是devicemapper驱动依赖&#xff09; yum install -y yum-utils device-mapper-persistent-data lvm2 设置stable镜像仓库&#xff08;使用阿里…

Linux:理解动静态库

一、前言 如果我们写了一些方法想给别人用&#xff1f;&#xff1f;有什么办法呢&#xff1f;&#xff1f; ——>(1)我直接把头文件和源文件给他&#xff08;.c.h&#xff09; ——>这样会让别人轻易看到你的实现 &#xff08;2&#xff09;把源文件打包成库&#xff…