qt信号和槽

Qt是一个跨平台的C++图形用户界面应用框架  91年奇趣科技开发

pro工程文件介绍    .pro就是工程文件(project),它是qmake自动生成的用于生产makefile的配置文件

QT       += core gui   //Qt包含的模块greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本包含 widgets模块TARGET = Qt_First   //生成exe文件的名称
TEMPLATE = app      //应用程序模板SOURCES += main.cpp\    //源文件mywidget.cppHEADERS  += mywidget.h  //头文件

安装和创建文件方法在上一章已经解决,接下来就是说具体知识总结

其他知识:命名规范

运行 ctrl+r

编译 ctrl+b

注释 ctrl+/

字体缩放 ctrl+鼠标滚轮

整行移动 ctrl+shift+上下箭头

自动对齐 ctrl+i

同名的h和cpp切换 F4

查找关键字 ctrl+f

帮助文档 直接找qt文档,或者左边有帮助

 在Qt程序中,最常用的控件之一就是按钮了,首先我们来看下如何创建一个按钮

按钮 PushButton

QPushButton * btn = new QPushButton; 头文件 #include <QPushButton>//设置父亲//如果想显示时候依赖在当前的窗口中,需要设置父窗btn->setParent(this);//设置文字btn->setText("德玛西亚");//移动位置btn->move(100,100);//第二种创建QPushButton * btn2 = new QPushButton("孙悟空",this);//重新指定窗口大小this->resize(600,400);//设置窗口标题this->setWindowTitle("第一个项目");//限制窗口大小this->setFixedSize(600,400);//就不能拉伸了

QPushButton----------QAbstractButton-----------QWidget  关系为孙父爷关系

上面代码中,一个按钮其实就是一个QPushButton类下的对象,如果只是创建出对象,是无法显示到窗口中的,所以我们需要依赖一个父窗口,也就是指定一个父亲利用setParent函数即可,如果想设置按钮上显示的文字利用setText,移动按钮位置用move

对于窗口而言,我们可以修改左上角窗口的标题setWindowTitle,重新指定窗口大小:resize,或者设置固定的窗口大小setFixedSize

对象树

如图所示,我们言简意赅  树的创建是由上向下,释放时是由下向上,很丝滑

但你如果自己做一个析构函数,你会发现析构顺序和销毁顺序不同

析构函数,先调用父亲但是不执行(就是找到),再调用儿子,执行

Qt窗口坐标体系

坐标体系:

以左上角为原点(0,0),X向右增加,Y向下增加。

对于嵌套窗口,其坐标是相对于父窗口来说的。

 信号和槽机制

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

举例1,人 2.摩擦 3.神灯 4.出神灯   
要做一个连接 将12与34连接起来 结果可以为人在摩擦---神灯后可以出神灯
1.信号发送者(指针)  2.发送的信号 地址 3.信号的接收者 指针 4.处理的槽函数 地址、
connect(myBtn,&MyPushButton::clicked,this,&MyWidget::close);

这个是用好封装的函数调用的地址,用qt帮助文档查找的

 

以下属于自定义信号和槽

widget.h中  
//设置老师和学生Teacher * zt;Student * st;

teacher.h中

    //自定义信号  写到signal下//1.返回值是void//2.只需要声明,不需要实现//3.可以有参数,可以发生重载
signals:void hungry();//空的void hungry(QString foodName);//传参
student.h中
signals: //自定义
//槽函数 写到public slots下,或者public下,或者全局函数,或者lambda
//返回值 void
//需要声明 需要实现
//可以有参数 可以重载
public slots:void treat();void treat(QString foodName);
};

 student.cpp中

void Student::treat()//加作用域
{qDebug()<<"请老师吃饭";
}
void Student::treat(QString foodName)//有参传递
{//QString转为char *//先调用toUtf-8转为QByteArray//再调用data 转为 char*qDebug()<<"请老师吃饭,老师要吃:  "<<foodName.toUtf8().data();//消去引号
}

ps:teacher.cpp中不用添加修改什么

widget.cpp中  这里是重点,反复看里面的代码

#include "widget.h"
#include "QPushButton"
#include "QDebug"
//Teacher老师类  Student学生类
//下课后,老师会发出饿了的信号,学生进行响应,请老师吃饭Widget::Widget(QWidget *parent): QWidget(parent)
{this->zt=new Teacher(this);//在窗口中连接信号槽this->st=new Student(this);//连接信号和槽
//    connect(this->zt,&Teacher::hungry,this->st,&Student::treat);//连接有参的信号和槽//函数指针指向函数地址
//    void(Teacher:: * teacherSignal)(QString)=&Teacher::hungry;
//    void(Student:: * studentSlot)(QString)=&Student::treat;
//    connect(this->zt,teacherSignal,this->st,studentSlot);//按键QPushButton *btn=new QPushButton;btn->setParent(this);btn->setText("下课");//无参void(Teacher:: * teacherSignal2)()=&Teacher::hungry;void(Student:: * studentSlot2)()=&Student::treat;connect(this->zt,teacherSignal2,this->st,studentSlot2);
//      老师饿了(--学生请客)//信号和槽拓展//1.信号连接信号                                //无参connect(btn,&QPushButton::clicked,this->zt,teacherSignal2);
//                              bool        >=       0//连接方式  点击按钮--老师饿了(--学生请客)//2.一个信号可以连接多个槽函数//3.多个信号可以绑定同一个槽函数//4.信号和槽的参数类型,必须是一一对应  传的信号是宫保鸡丁,接受的也必须是宫保鸡丁QString--QSt//5.信号的参数个数可以多于槽函数,反之不可以   例如(QString,int)---(QString)正确//6.相同个数的参数类型也要一一对应//7.可以利用disconnect断开信号槽的连接
//  disconnect(btn,&QPushButton::clicked,this->zt,teacherSignal2);断前面
//  disconnect(this->zt,teacherSignal2,this->st,studentSlot2);断后面//下课函数调用
//    classISOver();//连接作用//lanbda表达式QPushButton *btn2=new QPushButton;btn2->move(100,0);btn2->setParent(this);btn2->setText("aaa");//函数体内可以使用lambda所在范围内所有可见的局部变量[=](){btn2->setText("bbb");}();//->返回值类型int num=[]()->int{return 1000;}();qDebug()<<"num"<<num;//[=](){}推荐使用QPushButton * btn3=new QPushButton;btn3->setParent(this);btn3->move(200,200);btn3->setText("aaa");connect(btn3,&QPushButton::clicked,this,[=]()//优化了上面信号连接信号的有参{btn3->setText("ccc");this->st->treat("鱼香肉丝");//直接调槽函数   在connect中调另一个函数this->close();});//用=正确(复制一个,间接改)用&错误!(直接修改)}
void Widget::classISOver(){//触发自定义信号emit this->zt->hungry();emit this->zt->hungry("宫保鸡丁");
}
Widget::~Widget()
{
}

挑里面两个重点代码说说

这里是无参信号连接槽
  this->zt=new Teacher(this);//在窗口中连接信号槽this->st=new Student(this);//连接信号和槽connect(this->zt,&Teacher::hungry,this->st,&Student::treat);

这里是有参信号连接槽

//连接有参的信号和槽//函数指针指向函数地址void(Teacher:: * teacherSignal)(QString)=&Teacher::hungry;void(Student:: * studentSlot)(QString)=&Student::treat;connect(this->zt,teacherSignal,this->st,studentSlot);

注意:题目前提是

下课后,老师会发出饿了的信号,学生进行响应,请老师吃饭

所以添加一个触发信号,下课了,老师肚子饿了,学生请客吃饭,符合逻辑。

void Widget::classISOver(){//触发自定义信号emit this->zt->hungry();emit this->zt->hungry("宫保鸡丁");
}

信号连接信号    connect代码,点一下按钮,连接老师饿了,回到上面几行,老师饿了,学生请客

    //无参void(Teacher:: * teacherSignal2)()=&Teacher::hungry;void(Student:: * studentSlot2)()=&Student::treat;connect(this->zt,teacherSignal2,this->st,studentSlot2);
//      老师饿了(--学生请客)//信号和槽拓展//1.信号连接信号                                //无参connect(btn,&QPushButton::clicked,this->zt,teacherSignal2);
//                              bool        >      0//连接方式  点击按钮--老师饿了(--学生请客)

这里只能是无参调用,因为clicked为bool类型,如果后面teacherSignal2得到了参数   如:

emit this->zt->hungry("宫保鸡丁");

connect(btn,&QPushButton::clicked,this->zt,teacherSignal2);将此代码理解为clicked是bool类型为1,是信号,teacherSingnal2为槽函数,当传入参数时QString(宫保鸡丁)就为失败

因为

   1一个信号可以连接多个槽函数    2.多个信号可以绑定同一个槽函数  3.信号和槽的参数类型,必须是一一对应  传的信号是宫保鸡丁,接受的也必须是宫保鸡丁QString--QString4.信号的参数个数可以多于槽函数,反之不可以   例如(QString,int)---(QString)正确              5.相同个数的参数类型也要一一对应     
6.可以利用disconnect断开信号槽的连接

自定义信号槽需要注意的事项

  1. 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
  2. 信号和槽函数返回值是 void
  3. 信号只需要声明,不需要实现
  4. 槽函数需要声明也需要实现
  5. 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
  6. 使用 emit 在恰当的位置发送信号;
  7. 使用connect()函数连接信号和槽。
  8. 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
  9. 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
  10. 如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

信号槽的拓展

  1. 一个信号可以和多个槽相连

如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。

  1. 多个信号可以连接到一个槽

只要任意一个信号发出,这个槽就会被调用

  1. 一个信号可以连接到另外的一个信号

当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。

  1. 槽可以被取消链接

这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽

  1. 信号槽可以断开

利用disconnect关键字是可以断开信号槽的

  1. 使用Lambda 表达式

在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。

在连接信号和槽的时候,槽函数可以使用Lambda表达式的方式进行处理。后面我们会详细介绍什么是Lambda表达式

 

那人问了,那该怎么办呢?

lambda函数 

 引入lambda函数         Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

[capture](parameters) mutable ->return-type//Lambda表达式的基本构成

{

statement

}

[函数对象参数](操作符重载函数参数)mutable ->返回值{函数体}

函数对象参数;

[],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式          

  1. 空。没有使用任何函数对象参数。
  2. =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。

        3.&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。

 那么如何实现lambda   实现信号连接信号有参呢?

     //lanbda表达式QPushButton *btn2=new QPushButton;btn2->move(100,0);btn2->setParent(this);btn2->setText("aaa");//函数体内可以使用lambda所在范围内所有可见的局部变量[=](){btn2->setText("bbb");}();//->返回值类型int num=[]()->int{return 1000;}();qDebug()<<"num"<<num;//[=](){}推荐使用QPushButton * btn3=new QPushButton;btn3->setParent(this);btn3->move(200,200);btn3->setText("aaa");connect(btn3,&QPushButton::clicked,this,[=]()//优化了上面信号连接信号的有参{btn3->setText("ccc");this->st->treat("鱼香肉丝");//直接调槽函数   在connect中调另一个函数this->close();});//用=正确(复制一个,间接改)用&错误!(直接修改)}

精华代码在这


     connect(btn3,&QPushButton::clicked,this,[=]()//优化了上面信号连接信号的有参
     {
         btn3->setText("ccc");
        this->st->treat("鱼香肉丝");//直接调槽函数   在connect中调另一个函数
         this->close();

     });//用=正确(复制一个,间接改)用&错误!(直接修改)

直接调槽函数   在connect中调另一个函数 ,槽函数也是函数,所以在connect中直接调用

connect中加了一个lambda函数

另外有一个重点:

在lambda[]用=正确(复制一个,间接改)用&错误!(直接修改)

完结,收工 

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

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

相关文章

openssl ans1定义的实体

由于openssl中的ASN1的结构是通过宏来定义的&#xff0c;导致我们经常找不到他的结构在哪里&#xff0c;通过阅读rfc&#xff0c;并且对照OPENSSL&#xff0c;发现OPENSSL中的结构基本是按照相关rfc中的名称&#xff0c;在openssl中进行搜索&#xff0c;就能找到具体的定义了。…

在线制作假期承诺书,电子手写签名确认,一键导出打印。

假期将至&#xff0c;为积极落实安全管理规定&#xff0c;单位通常需要下发安全承诺书进行签字确认。 易查分可以实现网上下发安全承诺书通知&#xff0c;让查询者进行签名确认&#xff0c;还可以生成PDF&#xff0c;方便打印一人一张的纸质版承诺书&#xff0c;本次就来介绍如…

docker-compose安装及常用指令学习和harbor安装使用

文章目录 1 docker-compose1.1 docker-compose安装1.2 docker-compose卸载1.3 docker-compose常用命令 2 harbor安装使用2.1 harbor安装2.2 harbor使用 1 docker-compose ​ 在实际生产环境中&#xff0c;一个应用往往由许多服务构成&#xff0c;而 docker 的最佳实践是一个容…

java碳排放数据信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web碳排放数据信息管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环 境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为…

1.7 OVERARCHING GOALS

我们的主要目标是教读者如何对大规模并行处理器进行编程以实现高性能&#xff0c;我们的方法不需要大量的硬件专业知识。因此&#xff0c;我们将用许多页面来开发高性能并行程序的技术。而且&#xff0c;我们相信&#xff0c;一旦你发展正确的洞察力并以正确的方式进行&#xf…

阿里云ECS云服务器客户端下载

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

计算机网络-VLAN原理与配置

之前我们学习了以太网的基础知识&#xff0c;了解了网络交换设备的发展&#xff0c;交换机的工作原理&#xff0c;广播域和冲突域。 一、概述 还简单了解了以太网的CSMA/CD通讯机制&#xff0c;以太网是建立在CSMA/CD (Carrier Sense Multiple Access/Collision Detection&…

2024 电子科技大学 《820 计算机专业基础》真题及解析(更新中...)

数据结构算法题&#xff08;15 分&#xff0c;8 7&#xff09; 1. 比较一棵二叉树的终端节点到根节点的路径长度&#xff0c;路径长度为关键字之和&#xff0c;输出路径长度最短的终端节点。 输入&#xff1a;第一行输入一个整数 n, 表示结点的个数&#xff0c;第二行输入二叉…

Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行

环境: Rustdesk1.19 问题描述: Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行 解决方案: 1.查看源代码 pub async fn start_all() {crate::hbbs_http::sync::start();let mut nat_tested = false;check_zombie()

go work

vscode gopls插件工具依赖go work,否则会报错 https://github.com/golang/tools/blob/master/gopls/doc/workspace.md Go 1.18 新特性多模块工作区教程-让多模块开发变得简单 - Go语言中文网 - Golang中文社区

A2DP Source如何从android系统拿到音频数据

Android 13 简单来说就是两条本地socket通道&#xff0c;分别使用文件&#xff1a; #define A2DP_CTRL_PATH "/data/misc/bluedroid/.a2dp_ctrl" #define A2DP_DATA_PATH "/data/misc/bluedroid/.a2dp_data" A2DP_CTRL_PATH是控制通道&#xff0c;A2DP…

物联网协议Coap中Californium CoapClient解析

目录 前言 一、CoapClient对象 1、类定义 2、Client方法调用 二、发送请求 1、构建请求 2、发起请求 3、接收响应 总结 前言 在之前的博客中物联网协议Coap之Californium CoapServer解析&#xff0c;文中简单介绍了CoapServer的实现。在物联网开发环境中&#xff0c;除了…

给Flutter + FireBase 增加 badge 徽章,App启动器 通知红点。

在此之前需要配置好 firebase 在flutter 在项目中。&#xff08;已经配置好的可以忽略此提示&#xff09; Firebase 配置教程&#xff1a;flutter firebase 云消息通知教程 (android-安卓、ios-苹果)_flutter firebase_messaging ios环境配置-CSDN博客 由于firebase 提供的消息…

在Gitee上维护Erpnext源

在Gitee上维护Erpnext源 官方的frappe和erpnext地址: GitHub - frappe/frappe: Low code web framework for real world applications, in Python and Javascript GitHub - frappe/erpnext: Free and Open Source Enterprise Resource Planning (ERP) 1, 仓库地址输入frappe的官…

HAL——SPI

学习目标 掌握SPI配置方式掌握SPI读写操作 学习内容 需求 SPI配置 打开SPI1,选中全双工模式。观察下方自动生成的引脚&#xff0c;是否和自己开发板引脚对应。 修改引脚&#xff0c;来动右侧芯片引脚视图&#xff0c;找到开发板对应引脚&#xff0c;进行修改。 观察修改后的…

SpringBoot-Redis

依赖 <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId>配置 # 服务器连接端口 spring.redis.port6379 # 服务器地址 spring.redis.host127.0.0.1 # 数据库索引&#xff08;默认为0&#xff09…

【GitHub】-design-pattern-extend(设计模式扩展)

写在前面 偶然间看到一篇文章 《Java 中保持扩展性的几种套路和实现》&#xff0c;写的不错&#xff0c;但是类图画的差了点儿意思。于是&#xff0c;自己动手画了画&#xff0c;对其中的内容作了一些调整&#xff0c;对包做了进一步划分&#xff0c;便于理解消化。以下是对Git…

Linux rsh命令教程:远程shell命令的使用和注意事项(附案例详解和注意事项)

Linux rsh命令介绍 rsh&#xff08;remote shell&#xff09;提供用户环境&#xff0c;也就是Shell&#xff0c;以便指令能够在指定的远端主机上执行。rsh连接到指定的主机&#xff0c;并执行指定的命令。rsh将其标准输入复制到远程命令&#xff0c;将远程命令的标准输出复制到…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑多元不确定性和备用需求的微电网双层鲁棒容量规划》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及微电网&#xff08;Microgrid&#xff09;的双层鲁棒容量规划&#xff0c;考虑了多元不确定性和备用需求。让我们逐步解读这个标题&#xf…

【KD】知识蒸馏(knowledge distillation)简单介绍

最近学到了知识蒸馏的相关知识&#xff0c;来简单总结一下૮꒰ ˶• ༝ •˶꒱ა。 知识蒸馏 知识蒸馏&#xff0c;是一种模型压缩的手段。通过训练学生模仿教师的行为&#xff0c;将嵌入在大的教师模型中的知识迁移到小的学生模型。 例如&#xff0c;TinyBERT(Jiao et al.,2…