QT基础入门——信号和槽机制(二)

news2024/11/11 4:47:34

前言:

在Qt中,有一种回调技术的替代方法:那就是信号和机制。当特定事件发生时,会发出一个信号。Qt的小部件中有许多预定义的信号,但我们可以将小部件子类化,向它们添加自定义的信号。槽是响应特定信号的函数

一、QPushButton Class的创建

按钮控件头文件:#include<QPushButton>

#include "mywidget.h"
#include<QPushButton>



myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
    //创建一个按钮
    QPushButton * btn = new QPushButton;
    //btn->show();//show以顶层方式弹出窗口控件
    //让btn对象  依赖在myWidget窗口中
    btn->setParent(this);

    //显示文本
    btn->setText("第一个按钮");

}

myWidget::~myWidget()
{
}

#include "mywidget.h"
#include<QPushButton>



myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
   
    //创建第二个按钮,按照控件大小创建窗口
    QPushButton * btn2 = new QPushButton("第二个按钮",this);

    //移动btn2按钮
    btn2->move(100,100);

    //重置窗口大小
    resize(600,400);

    //设置固定窗口大小
    setFixedSize(600,400);

    //设置窗口标题
    setWindowTitle("窗口");
}

myWidget::~myWidget()
{
}

 二、对象树

当创建的对象在堆区时候,如果指定的父亲是object派生下来的类或者.QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。一定程度上简化了内存回收机制
 

1.创建: 

 

 

2. mypushbutton.h

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyPushButton(QWidget *parent = nullptr);

    ~MyPushButton();
signals:

};

#endif // MYPUSHBUTTON_H

3. mypushbutton.cpp

#include "mypushbutton.h"
#include <QDebug>

MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{
    qDebug() << "我的按钮类构造调用";
}

MyPushButton ::~MyPushButton()
{
    qDebug() << "我的按钮类析构";
}

4.mywidget.cpp

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{

    //创建一个自己按钮的对象
    MyPushButton * myBtn = new MyPushButton;
    myBtn->setText("我自己的按钮");

    myBtn->move(200,0);
    myBtn->setParent(this); //设置到对象树中
}

myWidget::~myWidget()
{
    qDebug() << "myWidget的析构调用";
}

5.运行结果 

三、QT坐标系 

坐标系:

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

 其坐标相对于父窗口而言

*四.信号和槽

connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))

信号槽的优点:

松散耦合﹐信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起

1.点击按钮关闭窗口

参数1   信号的发送者  

参数2   发送的信号(函数的地址)  

参数3   信号的接受者    

参数4   处理的槽函数(函数的地址)

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{

    //创建一个自己按钮的对象
    MyPushButton * myBtn = new MyPushButton;
    myBtn->setText("我自己的按钮");

    myBtn->move(200,0);
    myBtn->setParent(this); //设置到对象树中

    //需求   点击我的按钮关闭窗口
    //参数1  信号的发送者   参数2   发送的信号(函数的地址)   参数3   信号的接受者    参数4    处理的槽函数
    //connect(myBtn,&MyPushButton::clicked,this,&myWidget::close);
    connect(myBtn,&QPushButton::clicked,this,&QWidget::close);
}

myWidget::~myWidget()
{
    qDebug() << "myWidget的析构调用";
}

2.自定义信号和槽

(1)自定义信号

        写到signals下

        返回void

        需要声明,不需要实现

        可以有参数,可以重载

(2)自定义槽函数

        返回void

        需要声明,也需要实现

        可以有参数,可以重载

        写到public slot下或者public或者全局函数。

(3)当定义信号和槽出现重载

        需要利用函数指针明确指向函数地址

    void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;    

    void(Student:: *studentSlot)(QString) = &Student::treat;   

    connect(zt,teacherSignal,st,studentSlot);

        QsString ----》char *先转成OByteArray(.toUtf8())再转char *()

(4)信号连接信号

    无参信号和槽的连接  
    void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;  
  
    void(Student:: *studentSlot2)(void) = &Student::treat;    
        
    connect(zt,teacherSignal2,st,studentSlot2);   

    信号连接信号    
    connect(btn,&QPushButton::clicked,zt,teacherSignal2);

(5)断开信号  

 disconnect(zt,teacherSignal2,st,studentSlot2);

 3.代码实现

(1)student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QWidget>

class Student : public QWidget
{
    Q_OBJECT
public:
    explicit Student(QWidget *parent = nullptr);

signals:

public slots:
    //早期qt版本   必须写到public slots,高版本可以写到public或者全局下
    //返回值 void,需要声明也需要实现
    //可以有参数,可以发生重载
    void treat();
};

#endif // STUDENT_H

(2)teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
    //自定义信号  写到signals下
    //返回值是void,只需要声明,不需要实现
    //可以有参数,可以重载
    void hungry();


};

#endif // TEACHER_H

(3)widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <teacher.h>
#include <student.h>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    Teacher * zt;
    Student * st;

    void classIsOver();

};
#endif // WIDGET_H

(4)student.cpp

#include "student.h"
#include <QDebug.h>
Student::Student(QWidget *parent) : QWidget(parent)
{

}

void Student::treat()
{
    qDebug()<<"请老师吃饭";

}
void Student::treat(QString foodName)
{

    //QsString ----》char *先转成OByteArray(.toUtf8())再转char *()

    qDebug()<<"请老师吃饭,老师要吃"<<foodName.toUtf8().data();
}

(5)teacher.cpp

#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

(6)widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>

//Teacher 类  老师类
//Student 类  学生类
//场景:下课后老师触发一个信号,饿了,学生响应信号  请客吃饭

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建一个老师对象
    this->zt = new Teacher(this);
    //创建一个学生对象
    this->st = new Student(this);

//    //老师饿了,学生请客的连接
//    connect(zt,&Teacher::hungry,st,&Student::treat);

//    //调用下课函数
//    classIsOver();

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

    //调用下课函数
    classIsOver();

    //点击一个  下课的按钮,再触发下课
    QPushButton * btn = new QPushButton("下课",this);
    //重置窗口大小
    this->resize(600,400);
    //点击按钮触发下课
    //connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);

    //无参信号和槽的连接
    void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
    void(Student:: *studentSlot2)(void) = &Student::treat;
    connect(zt,teacherSignal2,st,studentSlot2);

    //信号连接信号
    connect(btn,&QPushButton::clicked,zt,teacherSignal2);

    //断开信号
    //disconnect(zt,teacherSignal2,st,studentSlot2);
    
    
    
}

void Widget::classIsOver()
{
    //下课函数调用后触发老师饿了的信号
    //emit zt->hungry();
    emit zt->hungry("鱼香肉丝");

}
Widget::~Widget()
{
    delete ui;
}

4.Lambda表达式 

C++11中的Lambda 表达式用于定义并创建匿名的函效对象,以简化编程工作。
[]  标识符   匿名函数

=  值传递

&  引用传递

()  参数     {}  实现体

mutable   修饰  值传递变量,可以修改拷贝出的数据,改变不了本体

返回值  []()  ->  int {}

最常用   [=](){}

    //利用Lambda表达式,实现点击按钮关闭窗口
    QPushButton *btn2 = new QPushButton;
    btn2->setText("关闭");
    btn2->move(100,0);
    btn2->setParent(this);
    connect(btn2,&QPushButton::clicked,this,[=](){
//       this->close();
//       emit zt->hungry("鱼香肉丝");
       btn2->setText("AAAAA");
    });

5.整体框架 

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

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

相关文章

静电监控系统的作用在哪

静电监控系统主要用于监测和管理静电的产生、传导和消除&#xff0c;以防止静电对生产过程和环境的损害。具体来说&#xff0c;静电监控系统的作用包括以下几个方面&#xff1a; 监测静电的产生和传导&#xff1a;静电监控系统可以实时监测生产现场的静电产生和传导情况&#…

【LeetCode热题100】--33.搜索旋转排序数组

33.搜索旋转排序数组 对于有序数组&#xff0c;使用二分查找&#xff1a; 该题只保证了部分有序&#xff0c;也能进行二分查找 在常规二分查找时查看当前mid分割出来的两部分[l,mid]和[mid1,r]&#xff0c;哪个部分是有序的&#xff0c;根据有序的那个部分确定我们该如何改变…

解决WPF+Avalonia在openKylin系统下默认字体问题

一、openKylin简介 openKylin&#xff08;开放麒麟&#xff09; 社区是在开源、自愿、平等和协作的基础上&#xff0c;由基础软硬件企业、非营利性组织、社团组织、高等院校、科研机构和个人开发者共同创立的一个开源社区&#xff0c;致力于通过开源、开放的社区合作&#xff…

k8s集群-6(daemonset job cronjob控制器)

Daemonset 一个节点部署一个节点 当有节点DaemonSet 确保全部 (或者某些) 节点上运行一个 Pod 的副本。加入集群时&#xff0c;也会为他们新增一个 Pod 。当有节点从集群移除时&#xff0c;这些Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。 DaemonSet 的典型用…

Integrity Plus for Mac,保障网站链接无忧之选

在如今数字化的时代&#xff0c;网站链接的完整性对于用户体验和搜索引擎排名至关重要。如果您是一位网站管理员或者经常需要检查网站链接的人&#xff0c;那么Integrity Plus for Mac&#xff08;Integrity Plus&#xff09;将成为您最好的伙伴。 Integrity Plus是一款专业的…

WS-FLV直播协议分析

一、简介 ws-flv&#xff08;websocket-flv&#xff09;是一种直播协议&#xff0c;其基于WebSocket来传输FLV格式的音视频。可以用来替代rtmp&#xff0c;解决其需要浏览器端依赖flash的问题&#xff1b;替代http-flv&#xff0c;解决浏览器同域名请求的最大并发数限制导致的浏…

英伟达NVIDIA驱动安装

一般&#xff0c;我们新的显卡上机或者新系统可能就需要重新安装显卡驱动。或者是我们在配置深度学习环境时候&#xff0c;需要手动安装驱动。 官网地址&#xff1a;官方高级驱动搜索 | NVIDIA 我们选择好自己需要的驱动后直接安装即可 下载的时候&#xff0c;选择自己需要的驱…

Swift SwiftUI CoreData 过滤数据 1

Xcode: Version 14.3.1 (14E300c) iOS: 16 预览&#xff1a; Code: import SwiftUI import CoreDatastruct TodosSearch: View {State private var search_title "测试"FetchRequest var todos_search: FetchedResults<Todo>init() {let request: NSFetchReq…

纯JS电子表格控件SpreadJS正式发布v16.2——新增甘特图插件

SpreadJS 是一款基于 HTML5 的纯前端电子表格控件&#xff0c;兼容 450 种以上的 Excel 公式&#xff0c;凭借其 “高性能、跨平台、与 Excel 高度兼容”的产品特性&#xff0c;备受以华为、苏宁易购、天弘基金等为代表的企业用户青睐。SpreadJS 为用户带来亲切的 Excel 使用体…

OpenGLES:3D立方体纹理贴图

效果展示 一.概述 前几篇博文讲解了OpenGLES绘制多种3D图形&#xff0c;并赋予丰富的色彩&#xff0c;但是在这些3D图形绘制过程中&#xff0c;有一点还没有涉及&#xff0c;就是纹理贴图。 今天这篇博文我会用如下六张图片对立方体进行纹理贴图&#xff0c;实现六个面都是贴…

Vscoe设置if __name__ == ‘__main__‘: 自动提示

解决Vscode 无 if __name__ __main__: 自动提示问题 配置步骤&#xff1a; 设置——》用户代码片段——》python.json配置文件——》添加"Print to console"项 添加代码内容&#xff1a; "Print to console": {"prefix": "main",&q…

数据可视化工具在成绩分析中的作用与意义

数据可视化是将数据转化为图表、图形和可交互式界面的过程&#xff0c;它在成绩分析中扮演着重要的角色。通过将学生成绩数据以图形化方式展示&#xff0c;数据可视化工具可以帮助教育者更好地理解和解释学生的表现&#xff0c;发现隐藏在数据背后的模式和趋势。本文将详细介绍…

添加驱动模块到内核的两种方法

添加驱动模块到内核的两种方法 1. 放在内核源代码树中 步骤总结&#xff1a; 新建文件夹编写Makefile、编写Kconfig修改上层Kconfig执行make menuconfig执行make zImage 或 make modules 1.1 源码放入文件夹 例如&#xff1a;添加一个按键字符设备模块 在内核目录下的 dri…

代码:对鱼眼相机图像进行去畸变处理

图像投影模型&#xff1a;针孔[fx, fy, cx, cy] 图像畸变模型&#xff1a;切向径向畸变[k1, k2, p1, p2] 说明&#xff1a;用于备忘 第一部分是常规的去畸变操作&#xff0c;在已知内参的情况下对鱼眼相机进行去畸变&#xff0c;这里使用的是remap映射在对图像去畸变后&#x…

毛玻璃 has 选择器卡片悬停效果

效果展示 页面结构 从上述的效果展示可以看到&#xff0c;页面是由多个卡片组成&#xff0c;并且鼠标悬停在卡片上时&#xff0c;会旋转用户图片并且韩式对应的用户信息框。 CSS3 知识点 :has 属性的运用 实现页面整体结构 <div class"container"><div…

复原akshare的股票代码缺失前面000代码

原始的akshare保存成文件&#xff0c;再读取时&#xff0c;代码会被自动转换为如下形式&#xff1a; 我们需要对每一个元素&#xff0c;补齐前面的0&#xff0c;将代码补充为6位 示例程序 import pandas as pdmy_df pd.read_csv("akshare下载文件.csv") my_df[代码…

【Linux基础】Linux发展史

&#x1f449;系列专栏&#xff1a;【Linux基础】 &#x1f648;个人主页&#xff1a;sunny-ll 一、前言 本篇主要介绍Linux的发展历史&#xff0c;这里并不需要我们掌握&#xff0c;但是作为一个合格的Linux学习者与操作者&#xff0c;这些东西是需要了解的&#xff0c;而且…

线程的概述

#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 功能&#xff1a;创建一个子线程 参数&#xff1a; -thread:传出参数&#xff0c;线程创建成功后&#xff0c;子线程的ID被写到…

SSRF+redis未授权漏洞复现

1.SSRF漏洞简介 SSRF&#xff08;Server-Side Request Forgery&#xff09;即服务器端请求伪造&#xff0c;是一种由攻击者构造攻击链传给服务器&#xff0c;服务器执行并发起请求造成安全问题的漏洞&#xff0c;一般用来在外网探测或攻击内网服务。当网站需要调用指定URL地址…

Inno Setup新手使用教程

1.编写脚本.iss文件 2.使用Inno Setup打开脚本 3.点击运行 4.打包好的文件在output文件夹下 注&#xff1a;运行不通过可能是文件不存在或者路径错误 推荐一个零声学院项目课&#xff0c;个人觉得老师讲得不错&#xff0c;分享给大家&#xff1a; 零声白金学习卡&#xff08;含…