【QT5】<总览二> QT信号槽、对象树及样式表

news2024/11/18 22:46:47

文章目录

前言

一、QT信号与槽

1. 信号槽连接模型

2. 信号槽介绍

3. 自定义信号槽

二、不使用UI文件编程

三、QT的对象树

四、添加资源文件

五、样式表的使用

六、QSS文件的使用


前言

承接【QT5】<总览一> QT环境搭建、快捷键及编程规范。若存在版权问题,请联系作者删除!


一、QT信号与槽

1. 信号槽连接模型

1.1 信号槽连接模型:

1.2 QT中信号槽的使用方式:

方式一:如下图所示,在ui设计器中的中下位置可以设置信号槽的四要素。下图实现了点击按钮就会关闭当前窗口的功能。

方式二:如下图所示,右击按钮,再点击“转到槽”,QT就会给MyWindow类自动在头文件中声明私有的void on_pushButton_clicked(); 同时也会转到源文件要求程序员实现点击的效果。

2. 信号槽介绍

2.1 概念:

  • 信号:在特定情况下被发射的事件。例如:PushButton最常见的信号就是鼠标单击时发射的click()信号。
  • 槽:对信号响应的函数。槽函数与普通的函数相比,不同在于:槽函数与指定的信号关联,当信号被发射时,该槽函数会被自动执行。

2.2 信号与槽的关联:

  • 方式:使用QObject::connect()函数。由于QT中所有类都是QObject的子类,因此可以省去QObject,其基本格式如下:
//sender 是发射信号的对象的名称
//signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数
//receiver 是接收信号的对象名称
//slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数
//SIGNAL和SLOT是Qt的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
  • 代码示例:
/* 1.mywindow.h头文件代码 */
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MyWindow; }
QT_END_NAMESPACE


class MyWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void pushButton_clicked();//自定义槽函数

private:
    Ui::MyWindow *ui;
};
#endif // MYWINDOW_H

/************************************************/

/* 2.mywindow.cpp代码  */
#include "mywindow.h"
#include "ui_mywindow.h"
#include <QDebug>

//MyWindow构造函数的具体实现
MyWindow::MyWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MyWindow)
{
    ui->setupUi(this);
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(pushButton_clicked()));
}

//MyWindow析构函数的具体实现
MyWindow::~MyWindow()
{
    delete ui;
}

//自定义槽函数的实现
void MyWindow::pushButton_clicked()
{
    static int i;
    qDebug() << i++ << " ";
}

2.3 信号与槽的解除连接:

  • disconnect(myObject, 0, 0, 0); 断开一切与 myObject 连接的信号或槽。
  • disconnect(myObject, SIGNAL(mySignal()), 0, 0); 断开所有连接到特定信号的东西。
  • disconnect(myObject, 0, myReceiver, 0); 与指定的接收者断开连接。

2.4 信号槽连接规则:

  • 一个信号可以连接多个槽(触发一个造成多个结果)
  • 多个信号可以连接同一个槽(多个触发源造成一个结果)
  • 一个信号可以连接另一个信号(连锁反应)

3. 自定义信号槽

3.1 自定义信号的语法:

//在类中使用signals关键字
//信号函数只声明不定义,并且返回值为void
signals:
    void sendMessage();//自定义信号函数

3.2 自定义槽的语法:

//使用slots自定义槽
//可以使用C++的三种权限符
//声明后必须给出定义
public slots:
    void goToClass();//自定义的槽函数

//槽函数定义
void Student::goToClass()
{
    qDebug() << "学生上课!" << endl;
}

3.3 案例:

背景:学校发出通知,学生收到后回到班级上课。根据此情景,创建School和Student类,并且在School类中自定义信号“发出通知”,在Student类中自定义槽“去班级”。为了简单演示,我们在MainWindow类中添加School和Studen类对象作为成员变量,在MainWindow的构造函数中创建对象,并构建“学校->通知->学生->上课”的信号槽连接,同时emit发射该信号,来观察实验现象。

①School.h:

#ifndef SCHOOL_H
#define SCHOOL_H

#include <QObject>

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

signals://自定义信号
    void sendMessage();//学校通知

};

#endif // SCHOOL_H

②Student.h:

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots://自定义槽
    void goToClass();

};

#endif // STUDENT_H

③Student.cpp:

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

Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::goToClass()
{
    qDebug() << "学生上课!" << endl;
}

④MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "school.h"
#include "student.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    School *school;
    Student *student;
};
#endif // MAINWINDOW_H

⑤MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    school = new School(this);
    student = new Student(this);
    connect(school, SIGNAL(sendMessage()), student, SLOT(goToClass()));//信号与槽的连接
    emit school->sendMessage();//发射信号
}

MainWindow::~MainWindow()
{
    delete ui;
    delete school;
    delete student;
}


二、不使用UI文件编程

本章以按钮控件为例,说明仅编写代码来创建按钮。

步骤一:创建工程时取消勾选"Generate form":

步骤二:在mainwindow.h中声明按钮成员对象和头文件<QPushButton>:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    QPushButton *pushButton;//按钮对象
};
#endif // MAINWINDOW_H

步骤三:在mainwindow.cpp中的构造函数里创建按钮对象,并设置相关属性:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    pushButton = new QPushButton(this);         //实例化按钮
    pushButton->setText("我是按钮");             //设置按钮文本
    pushButton->setGeometry(50, 100, 100, 50);  //设置按钮位置
    this->resize(800, 480);                     //设置当前窗口大小
}

MainWindow::~MainWindow()
{
    delete pushButton;
}

三、QT的对象树

1. 为什么需要设置父对象?

答:因为需要将某些控件附着于父对象,以便能跟着父对象一起移动,方便控件的管理。

2. 如何设置父对象?

答:有构造函数传参和调用setparent()两种方式,如下所示:

//方式一:构造函数传入父对象地址
pushButton = new QPushButton(this);
//方式二:调用setParent函数
pushButton->setParent(this);

3. QT的对象树机制

答:父对象在调用析构函数前,会将附着于其上面所有的对象析构,再调用自己的析构函数。因此,可以不用显式地delete某些附着的对象,QT的对象树机制会自动将其销毁。


四、添加资源文件

有时需要外部的图片等资源,因此需要将资源文件添加进QT。

步骤一:将资源文件放置于当前工程目录下。

步骤二:添加"QT Resource File":

步骤三:添加资源路径的目录:

步骤四:添加外部图片:


五、样式表的使用

第四章已经加载了外部图片资源文件,本章改变样式表(stylesheet)将该图片呈现于窗口中。若不知道如何编写样式表的代码,可以去“帮助”中查找“stylesheet”查看“Qt Style Sheets Reference ”。

步骤一:在ui设计器中将QLable控件拖拽至窗口中:

步骤二:右击该控件,选中"改变样式表",添加图片:


六、QSS文件的使用

在第五章中,我们利用ui设计器来改变样式表从而加载外部图片。相应地,我们可以通过写代码的方式来改变样式表从而改变某些控件的外观。但是,当样式表书写过多时会影响我们代码的可读性。因此,可以通过qss文件来汇总这些样式表,而不需要在主程序中书写这些样式表。

原始效果:在Widget类的构造函数中写这些样式表。

我们将上述的样式表代码转移到qss文件中,减少主程序代码的复杂度。若不知道怎么写qss样式表,可以参考Qt QSS样式表总结

步骤一:新建qss文件:

步骤二:编辑qss文件:

步骤三:main()中加载qss文件:

运行结果:

/* 加载QSS文件 */
QFile file(":/style.qss");
if (file.exists()){
    file.open(QFile::ReadOnly);//只读方式打开
    QString styleSheet = QLatin1String(file.readAll());//字符串方式保存结果
    qApp->setStyleSheet(styleSheet);//设置全局样式
    file.close();//关闭文件
}

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

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

相关文章

计算机发展史 | 从起源到现代技术的演进

computer | Evolution from origins to modern technology 今天没有参考资料哈哈 PPT&#xff1a;&#xff08;评论区&#xff1f;&#xff09; 早期计算工具 算盘 -算盘是一种手动操作的计算辅助工具&#xff0c;起源于中国&#xff0c;迄今已有2600多年的历史&#xff0c;是…

告别鼠标:蓝牙无线安卓模拟鼠标,绘图板,手写板操作电脑PC端,卡卡罗特也说好,儿童节快乐

家人们&#xff0c;上链接了&#xff1a;https://download.csdn.net/download/jasonhongcn/89387887 横屏模式&#xff1a; 竖屏模式&#xff1a; 操作说明&#xff1a; 1. 手势滑动模拟鼠标移动 2. 界面如果有滚动条&#xff0c;右手指按紧&#xff0c;通过左手指移动实现…

智慧医疗新纪元:可视化医保管理引领未来

在数字化浪潮席卷全球的今天&#xff0c;我们的生活正在经历前所未有的变革。其中&#xff0c;智慧医保可视化管理系统就像一股清新的风&#xff0c;为医疗保障领域带来了全新的活力与可能。 想象一下&#xff0c;在繁忙的医院里&#xff0c;患者和家属不再需要为了查询医保信息…

适合航天航空的国产FTP替代软件

在宇宙探索的旅程中&#xff0c;航空和航天领域总是站在科技的最前沿&#xff0c;对数据传输的要求特别高。随着信息量急剧增加和安全威胁的复杂化&#xff0c;传统的FTP软件已经不能满足这个高端领域的需要了。因此&#xff0c;找到一款适合航空和航天领域的FTP替代软件&#…

SQLServer 查询指定数据库名和表名及表结构等

查询当前数据库中所有表名&#xff0c;不用指定数据库&#xff0c;选中某数据库直接执行SQL就好 -- U:所有用户表名; S:所有系统表名;V:所有视图表名 SELECT name FROM sysobjects WHERE xtypeU OR xtypeS OR xtypeV 查询指定数据库数据库中所有表名&#xff0c; SELECT TAB…

ad18学习笔记21:焊盘设置Paste Mask Expansion(锡膏层延伸)

在pcb上放置焊盘的时候&#xff0c;可以对焊盘进行设置&#xff0c;可以用默认的规则&#xff0c;可以用自定义的规则&#xff0c;网上很少看到自定义的规则怎么用。 参考了官方的说明文档&#xff0c;我只是稍微补充了一下 paste mask与solder mask有哪些区别_paste mask与s…

【30天精通Prometheus:一站式监控实战指南】第10天:blackbox_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

isp效果库相关参数——镜像翻转

前言 之前一直比较忙着接触新工作内容&#xff0c;所以有一段搁置期&#xff0c;但是工作中的知识点还是有一直记录的&#xff0c;只是没空发出来&#xff0c;毕竟需要先熟悉才能总结内容&#xff0c;接下来的几天会连着发布 不同的产品数据手册有着不同的叫法但是统一的意思离…

怎么实现车间生产设备数据文件比传统FTP的精准快速管控?

在现代制造业中&#xff0c;数据管理的重要性日益凸显。车间生产设备产生的数据文件需要被精确、快速地管控&#xff0c;以确保生产效率和产品质量。传统上&#xff0c;文件传输协议&#xff08;FTP&#xff09;被广泛用于数据传输&#xff0c;但它存在一些明显的局限性。 传统…

三十七、openlayers官网示例Earthquakes Heatmap解析——在地图上加载热力图

官网demo地址&#xff1a; Earthquakes Heatmap 这篇主要介绍了热力图HeatmapLayer HeatmapLayer 是一个用于在地图上显示热力图的图层类型&#xff0c;通常用于表示地理数据中的密度或强度。例如&#xff0c;它可以用来显示地震、人口密度或其他空间数据的热点区域。在这个示…

2024050302-重学 Java 设计模式《实战享元模式》

重学 Java 设计模式&#xff1a;实战享元模式「基于Redis秒杀&#xff0c;提供活动与库存信息查询场景」 一、前言 程序员&#x1f468;‍&#x1f4bb;‍的上下文是什么&#xff1f; 很多时候一大部分编程开发的人员都只是关注于功能的实现&#xff0c;只要自己把这部分需求…

flutter as连接网易模拟器

网易模拟器下载 Mac 使用MuMu模拟器调试 Flutter开发 Android Studio 安装第三方模拟器—网易MuMu Mac 安卓Studio使用外部模拟器 Mac电脑&#xff1a;Android Studio 连接 MUMU 网易模拟器 Mac 上 Android Studio 链接网易 MuMu 模拟器调试 在 .zshrc 中设置 adb 二进制文…

计算机毕业设计 | 基于node(Koa)+vue 高校宿舍管理系统 宿舍可视化(附源码)

1&#xff0c;绪论 1.1 项目背景 随着科技的发展&#xff0c;智能化管理越来越重要。大学生在宿舍的时间超过了1/3&#xff0c;因此良好的宿舍管理对学生的生活和学习极为关键。学生宿舍管理系统能够合理安排新生分配宿舍&#xff0c;不浪费公共资源&#xff0c;减轻学校管理…

VBA excel 表格将多行拆分成多个表格或 文件 或者合并 多个表格

excel 表格 拆分 合并 拆分工作表按行拆分为工作表工作表按行拆分为工作薄 合并操作步骤 拆分 为了将Excel中的数万行数据拆分成多个个每个固定行数的独立工作表&#xff0c;并且保留每个工作表的表头&#xff0c;你可以使用以下VBA脚本。这个脚本会复制表头到每个新的工作表&…

opencv进阶 ——(十)图像处理之基于dlib人脸检测与识别

Dlib是一个功能丰富的C库&#xff0c;设计用于构建复杂的软件系统&#xff0c;尤其在机器学习、计算机视觉和数值计算等领域有着广泛的应用。以下是对Dlib的简要介绍&#xff1a; 特性&#xff1a; 机器学习算法&#xff1a;Dlib包含了各种机器学习算法&#xff0c;如支持向量机…

java分布式的ACP是什么

ACP 1、ACP是什么 一致性&#xff08;Consistency&#xff09;&#xff1a;在分布式系统中&#xff0c;当更新操作完成之后&#xff0c;所有节点在同一时间看到的数据是一致的。换句话说&#xff0c;对于任何数据的读取&#xff0c;都会得到最后写入的数据。可用性&#xff0…

鸿蒙开发接口安全:【@ohos.userIAM.userAuth (用户认证)】

用户认证 说明&#xff1a; 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import userIAM_userAuth from ohos.userIAM.userAuth;完整示例 // API version 6 import userIAM_userAuth from ohos.use…

学习笔记——路由网络基础——静态路由(static)

三、静态路由(static) 1、静态路由 (1)定义 静态路由(Static)&#xff1a;由管理员手动配置和维护的路由。静态路由配置简单&#xff0c;被广泛应用于网络中。此外还可以实现负载均衡和路由备份。 静态路由默认优先级为60&#xff0c;如果想在多条静态路由中让某条路由优选…

图片裁剪与上传处理方案 —— 基于阿里云 OSS 处理用户资料

目录 01: 通用组件&#xff1a;input 构建方案分析 02: 通用组件&#xff1a;input 构建方案 03: 构建用户资料基础样式 04: 用户基本资料修改方案 05: 处理不保存时的同步问题 06: 头像修改方案流程分析 07: 通用组件&#xff1a;Dialog 构建方案分析 08: 通用组件&…

宝兰德参编!《2023年中国数据库年度行业分析报告》正式发布

近日&#xff0c;墨天轮发布 《2023年中国数据库年度行业分析报告》&#xff08;以下简称《报告》&#xff09;。宝兰德深度参与《报告》重要章节内容的编写工作&#xff0c;凭借在中间件领域深厚的技术沉淀和丰富的实践经验&#xff0c;输出了大量具有专业性和前瞻性的意见&am…