三、Qt核心与Qt类库

一、Qt核心:元对象系统

1、Qt核心特点

  • Qt对标准C++进行了扩展,引入了一些新的概念和功能
  • 元对象编译器(MOC)是一个预处理器,先将Qt的特性程序转为标准C++程序,再由标准C++编译器进行编译
  • Qt为C++语言增加的特性在Qt Core模块中实现,由Qt的元对象系统实现。包括信号与槽机制、实行系统、动态类型转换等。使用信号与槽机制,只有添加Q_OBJECT宏,moc才能对类中的信号与槽进行预处理。

2、元对象系统

  • QObject类是所有使用元对象的类的基类
  • 在一个类的private部分声明private Q_OBJECT宏
  • MOC(元对象编译器)为每个QObject的子类提供必要代码。

二、Qt核心:属性系统、信号与槽

1、属性系统

Q_PROPERTY宏定义一个返回类型为type,名称为name的属性.
Q_PROPERTY(type nameREAD getFunction[WRITE setFunction][RESET resetFunction][NOTIFY notifySignal][DESIGNABLE bool][SCRIPTABLE bool][STORED bool][USER bool][CONSTANT][FINAL])

(1)创建属性

class QMyWidGet : public QWidget
{Q_OBJECTQ_PROPERTY(bool focus READ hasFocus)Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)Q_PROPERTY(QCursor cursor READ cursor WRITE SetCursor RESET unsetCursor)
public:explicit QMyWidget(QWidget *parent = nullptr);
};

(1)使用属性

setProperty可以在运行时为类定义一个新的属性,称之为动态属性。
QPushButton *button = new QPushButton;
QObject *object = button;
object->setProperty("flat", true);
bool isFalt = object->property("flat");

2、类的附加信息

Q_OBJECT
Q_CLASSINFO("author", "ZhangSan")
Q_CLASSINFO("compay", "XXX")
Q_CLASSINFO("version"' "1.1.1")QMyWidget *myWidget = new QMyWidget;
QDebug()<<myWidget->metaObject()->classInfo(0).name();
QDebug()<<myWidget->metaObject()->classInfo(0).value();
QDebug()<<myWidget->metaObject()->classInfo(1).name();
QDebug()<<myWidget->metaObject()->classInfo(1).value();

在这里插入图片描述

3、信号与槽

(1)原型

    static QMetaObject::Connection connect(const QObject *sender, const char *signal,const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,const QObject *receiver, const QMetaMethod &method,Qt::ConnectionType type = Qt::AutoConnection);inline QMetaObject::Connection connect(const QObject *sender, const char *signal,const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
最后一个参数Qt::ConnectionType表示信号与槽之间的关联方式
  • Qt::AutoConnection(默认值):自动确定关联方式
  • Qt::DirectConnection:信号被发射时,槽立即执行,槽函数与信号在同一个线程
  • Qt::QueuedConnection:事件循环回到接受者线程后执行槽,槽与信号在不同线程
  • Qt::BlockingQueuedConnection:信号线程会被阻塞直到槽函数执行完毕,当槽函数与信号在同一个线程,会导致死锁。

(2)使用

// 如果信和槽函数都带有参数,需要注明参数类型
connect(spinFontSize, SIGNAL(valueChanged(int)), this,SLOT(on_spinBoxFontSize_valueChanged(int)));
// 当信号名称(包括参数)唯一时,可以使用以下绑定
connect(spinFontSize, &QSpinBox::valueChanged, this,MainWindow::on_spinBoxFontSize_valueChanged);

(3)自定义信号

在槽函数里,使用QObject::sender()可以回去信号发射者的指针
QSpinBox *spinbox = qobject_cast<QSpinBos*>(sender());
class QPersen : public QObject
{Q_OBJECT
private:int m_age = 10;
public:voud incAge();
signals:void ageChanged(int value);	// 信号函数
};
void QPerson::incAge()
{m_age++;emit ageChanged(m_age);	//发射信号
}
信号函数必须无返回值,但可以由输入参数,信号函数无需实现,只需要在某些条件下发射信号。

三、元对象系统特性测试

在这里插入图片描述

1、创建项目(基于QWidget)

2、添加UI

在这里插入图片描述

3、添加QPerson类,基于QObject

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

#ifndef QPERSON_H
#define QPERSON_H#include <QObject>class QPerson : public QObject
{Q_OBJECTQ_CLASSINFO("author", "liutt")Q_CLASSINFO("compay", "XXX")Q_CLASSINFO("version", "1.1.1")// 添加属性Q_PROPERTY(unsigned age READ age WRITE setAge NOTIFY ageChanged)Q_PROPERTY(QString name MEMBER m_strName)   //MEMBER 绑定变量Q_PROPERTY(int score MEMBER m_nScore)private:unsigned int m_nAge = 10;QString m_strName;int m_nScore = 79;public:explicit QPerson(QString strName, QObject *parent = nullptr);unsigned int age();void setAge(unsigned int value);void incAge();signals:void ageChanged(unsigned int value);public slots:
};#endif // QPERSON_H
#include "qperson.h"QPerson::QPerson(QString strName, QObject *parent) : QObject(parent)
{m_strName = strName;
}unsigned int QPerson::age()
{return m_nAge;
}void QPerson::setAge(unsigned int value)
{m_nAge = value;emit(ageChanged(m_nAge));
}void QPerson::incAge()
{m_nAge++;emit(ageChanged(m_nAge));
}

4、添加信号与槽功能

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "qperson.h"namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private:void on_ageChanged(unsigned int value);private slots:void on_btnBoyInc_clicked();void on_btnGirlInc_clicked();void on_btnClassInfo_clicked();void on_spin_valueChanged(int value);private:Ui::Widget *ui;QPerson *boy;QPerson *girl;};#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"#include <QMetaClassInfo>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);ui->spinBoxBoy->setProperty("isBoy", true);ui->spinBoxGirl->setProperty("isBoy", false);boy = new QPerson("小乐");boy->setProperty("score", 60);boy->setProperty("age", 12);boy->setProperty("sex", "boy");connect(boy, &QPerson::ageChanged, this, &Widget::on_ageChanged);girl = new QPerson("小美");girl->setProperty("score", 70);girl->setProperty("age", 11);girl->setProperty("sex", "girl");connect(girl, &QPerson::ageChanged, this, &Widget::on_ageChanged);ui->spinBoxBoy->setValue(12);ui->spinBoxGirl->setValue(11);connect(ui->spinBoxBoy, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));connect(ui->spinBoxGirl, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));
}Widget::~Widget()
{delete ui;
}void Widget::on_spin_valueChanged(int value)
{Q_UNUSED(value)QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());if(spinBox->property("isBoy").toBool()) {boy->setAge(spinBox->value());}else {girl->setAge(spinBox->value());}
}void Widget::on_ageChanged(unsigned int value)
{Q_UNUSED(value)QPerson *pPerson = qobject_cast<QPerson*>(sender());QString strName = pPerson->property("name").toString();QString strSex = pPerson->property("sex").toString();unsigned int nAge = pPerson->age();ui->plainTextEdit->appendPlainText(strName+","+strSex+QString::asprintf(",年龄=%d", nAge));
}void Widget::on_btnBoyInc_clicked()
{boy->incAge();
}void Widget::on_btnGirlInc_clicked()
{girl->incAge();
}void Widget::on_btnClassInfo_clicked()
{const QMetaObject* meta = boy->metaObject();ui->plainTextEdit->clear();ui->plainTextEdit->appendPlainText("类元对象信息");ui->plainTextEdit->appendPlainText(QString("类名称:%1").arg(meta->className()));ui->plainTextEdit->appendPlainText("property: ");for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) {QMetaProperty prop = meta->property(i);const char *propName = prop.name();QString strPropValue = boy->property(propName).toString();ui->plainTextEdit->appendPlainText(QString("属性名称:%1,属性值:%2").arg(propName, strPropValue));}ui->plainTextEdit->appendPlainText("classInfo: ");for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); ++i) {QMetaClassInfo classInfo = meta->classInfo(i);ui->plainTextEdit->appendPlainText(QString("类信息名称:%1,类信息值:%2").arg(classInfo.name(), classInfo.value()));}
}

四、Qt全局定义

1、Qt全局定义

<QtGlobal>头文件包含了Qt类库的一些全局定义:
  • 基本函数类型
  • 函数

(1)Qt数据类型

typedef signed char qint8;         /* 8 bit signed */
typedef unsigned char quint8;      /* 8 bit unsigned */
typedef short qint16;              /* 16 bit signed */
typedef unsigned short quint16;    /* 16 bit unsigned */
typedef int qint32;                /* 32 bit signed */
typedef unsigned int quint32;      /* 32 bit unsigned */
typedef long long qint64;           /* 64 bit signed */
typedef unsigned long long quint64; /* 64 bit unsigned */

(2)宏定义

QT_VERSION	数值版本
QT_VERSION_CHECK()	// QT_VERSION_CHECK(5,0,0)
Q_BYTE_ORDER		// 系统内存字节序
Q_BIG_ENDIAN		// 大端字节序
Q_LITTLE_ENDIAN		// 小端字节序
Q_DECL_IMPORT		// 共享库导入
Q_DECL_EXPORT		// 共享库导出
Q_DECL_OVERRIDE		// 用于重载虚函数,没有被重载则报错
Q_DECL_FINAL		//	虚函数定义为最终级别,不能被重载
Q_UNUSED(name)		// 在函数中定义不在函数中使用的参数
foreach(variable, container)	// 用于容器遍历
forever 			//构造一个无线循环
qDebug(const char* message, ...)	// 输出日志,格式化

五、容器类

1、Qt容器

Qt的容器类比STL中的容器类更轻巧,安全和易用

顺序容器:QList(下标索引),QLinkKedList(不支持下标索引),QVector,QStack,QQueue
关联容器:QMap,QMultiMqp,QHash,QMultiHash,QSet

2、STL类型迭代器

容器类只读迭代器迭代器
QList,QQueueQList::const_iteratorQList::iterator
QLinkedListQLinkedList::const_iteratorQLinkedList::iterator
QVector,QStackQVector::const_iteratorQVector::iterator
QSetQSet::const_iteratorQSet::iterator
QMap<Key,Value>,QMultiMap<Key,Value>QMap<Key,Value>::const_iteratorQMap<Key,Value>::iterator

五、Qt类库的模块

Qt类的模块可以分为几大类:
  • Qt基本模块(Qt Essentials):提供了Qt的所有平台的基本功能
  • Qt附加模块(Qt Add-Ons):实现一些特定功能的提供附加价值的模块
  • 增值模块(Value-AddModules):单独发布的提供额外价值的模块或工具
  • 技术预览模块(Technology Preview Modules):一些处于开发阶段,但是可以最为技术预览使用的模块
  • Qt工具(Qt Tools):帮助应用程序开发的一些工具

1、Qt基本模块

Qt Core					其他模块都用的核心非图形类
Qt GUI					设计GUI界面的基础类,包括OpenGL
Qt Multimedia			音频、视频、摄像头和广播功能的类
Qt Multiply Widgets		实现多媒体的界面租界类
Qt Network				实现网络编程更简单和轻便的类
Qt QML					用于QML和JavaScript语言的类
Qt Quick				英语构建具有定制用户界面的动态应用的声明框架
Qt Quick Controls		创建桌面样式用户界面,基于Qt Quick的用户界面控件
Qt Quick Dialogs		用于Qt Quick的系统对话框类型
Qt Quick Layouts		用于Qt Quick2界面元素的布局项
Qt SQL					使用SQL数据库操作
Qt Test					用于应用程序的库进行单元测试的类
Qt Widgets				用于构建GUI界面的C++图形组件类
qmake构建时,Qt GUI模块时自动被加入项目的,如果项目不适用GUI功能,使用以下指令取消
QT-=gui
其他模块一般不会被自动加入,在项目使用到某个模块,可以在项目配置中添加:
QT+=sql
QT+=multimedia multimediawidgets

2、Qt工具

Qt Designer		用于扩展Qt Designer的类
Qt Help			在应用程序中继承在线文档
QtUI Tools		操作Qt Designer生成的窗体的类

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

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

相关文章

提升开发效率:npm包管理器的使用技巧

文章目录 一、npm简介二、npm的基本操作1. 安装Node.js和npm2. 创建和管理项目3. 安装依赖4. 卸载依赖5. 更新依赖 三、npm的高级特性1. 使用不同版本的依赖项2. 查看已安装的依赖项和它们的版本信息3. 运行脚本命令 《Node.js从入门到精通&#xff08;软件开发视频大讲堂&…

09-生成器模式(Builder)模式

意图 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 理解 如果构建一个对象的的过程会比较复杂&#xff0c;或者说在写代码的过程中&#xff0c;需要比较频繁地构建某个对象&#xff0c;那么可以针对这个对象写一个专门用于构建这…

2024前端炫酷源码分享(附效果图及在线演示)

分享10款非常有趣的前端特效源码 其中包含css动画特效、js原生特效、svg特效以及小游戏等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 GSAP-火箭动画特效 GSAP 火箭动画 当氮气充足的情况下 火箭会冲出 并继续飞行 图片…

C#,字符串匹配算法(模式搜索)Z算法的源代码与数据可视化

Z算法也是模式搜索&#xff08;Pattern Search Algorithm&#xff09;的常用算法。 本文代码的运算效果&#xff1a; 一、Z 算法 线性时间模式搜索算法的Z算法&#xff0c;在线性时间内查找文本中模式的所有出现。 假设文本长度为 n&#xff0c;模式长度为 m&#xff0c;那么…

【Spring Cloud 】进阶之Config配置中心

目录 config大致的一个思路&#xff1a; 二&#xff0c;前期准备 2.1导入依赖 2.2编写bootstrop.yml&#xff1a; 三&#xff0c;编写Controller类 3.1获取单个配置类信息 3.2获取多个配置类信息 &#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f3…

Linux习题6

解析&#xff1a;排序必须得是rwx,所以B不对 解析&#xff1a; /etc/resolv.conf&#xff1a;是DNS配置文件。在网卡配置文件中进行配置&#xff0c;默认情况下&#xff0c;网卡配置文件DNS优于/etc/resolv.conf。 /etc/hostname&#xff1a;在centos7&#xff0c;配置主机名…

Linux时间同步和时间设置

时间分为&#xff1a; 1、hwclock&#xff1a;用于查看硬件时间 hwclock -r&#xff08;--show&#xff1a;读取硬件时钟并打印结果&#xff09; &#xff1a;查看硬件时间 hwclock -s &#xff1a;系统时间向硬件时间同步 hwclock -w &#xff1a;硬件时间向系统时间同步 …

我的第一个前端项目,vue项目从零开始创建和运行

​入门前端&#xff0c;从基础做起&#xff0c;从零开始新建项目 背景&#xff1a;VUE脚手架项目是一个“单页面”应用&#xff0c;即整个项目中只有1个网页&#xff01; 在VUE脚手架项目中&#xff0c;主要是设计各个“视图组件”&#xff0c;它们都是整个网页中某个部分&…

TypeScript 从入门到进阶之基础篇(六) 类型(断言 、推论、别名)| 联合类型 | 交叉类型

系列文章目录 TypeScript 从入门到进阶系列 TypeScript 从入门到进阶之基础篇(一) ts基础类型篇TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇TypeScript 从入门到进阶之基础篇(三) 元组类型篇TypeScript 从入门到进阶之基础篇(四) symbol类型篇TypeScript 从入门到进阶…

自用PHP在线Access转html表格小功能(快速预览access)

自用PHP在线Access转html表格小功能(支持大文件上传,得到一表一文件) 本工具用于Access数据表转html下载供预览,特别适合各类程序员。 开发环境(可能只支持)Windows IIS PHP5.4 其他系统或新版本都不支持 <?php /* //自用PHP在线Access转html表格小功能(支持大文件上传,得…

一篇五分生信临床模型预测文章代码复现——Figure 10.机制及肿瘤免疫浸润(十)——Cibersort——完结

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

关于目标检测中按照比例将数据集随机划分成训练集和测试集

1. 前言 在做目标检测任务的时候&#xff0c;不少网上的数据&#xff0c;没有划分数据集&#xff0c;只是将数据和标签放在不同的文件夹下&#xff0c;没有划分数据集 虽然代码简单&#xff0c;每次重新编写还是颇为麻烦&#xff0c;这里记录一下 如下&#xff0c;有的数据集…

常见的缓存淘汰算法

FIFO、LRU、LFU 和 WindowTinyLFU 是常见的缓存淘汰算法&#xff0c;用于决定在缓存容量不足时应该如何选择要淘汰的数据。 常见的缓存淘汰算法包括&#xff1a; FIFO&#xff08;先进先出&#xff09;算法&#xff1a;按照数据最早进入缓存的顺序进行淘汰。即&#xff0c;最先…

HNU-数据库系统-实验3-数据库设计

数据库系统 课程实验3数据库设计 计科210X 甘晴void 202108010XXX 目录 文章目录 数据库系统 课程实验3<br>数据库设计实验目的实验内容实验重难点实验环境实验过程&#xff08;0&#xff09;数据库需求描述&#xff08;1&#xff09;数据库概念结构设计E-R图实体图书馆…

openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位

文章目录 openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位188.1 磁盘满故障引起的core问题188.1.1 问题现象188.1.2 原因分析188.1.3 处理办法 188.2 GUC参数log_directory设置不正确引起的core问题188.2.1 问题现象188.2.2 原因分析188.2.3 处理办…

利用ChatGLM3构建Prompt实现Text2SQL

之前使用ChatGLM3的自定义工具实现了查询MySQL数据库&#xff0c;但感觉功能还是比较受限。 https://blog.csdn.net/weixin_44455388/article/details/135270879?spm1001.2014.3001.5501 使用ChatGLM3实现Text2SQL 前言Text2SQL的构建第一阶段&#xff1a;SQL脚本构建&#xf…

软件工程_复习

软件工程 软件危机(1968 60年代) 产生软件危机的原因: 一方面与软件本身的特点有关,另一方面也和软件开发和维护的方法不正确有关。 与软件本身特点有关: 1.软件不同于硬件,软件是计算机系统中的逻辑部件,缺乏“可见性”,管理和控制软件开发过程相当困难 2.软件在运行过…

Python笔记06-文件操作

文章目录 文件的编码文件读取文件写入文件追加 文件的编码 编码技术即&#xff1a;翻译的规则&#xff0c;记录了如何将内容翻译成二进制&#xff0c;以及如何将二进制翻译回可识别内容。算机中有许多可用编码&#xff1a;UTF-8、GBK、Big5等 不同的编码&#xff0c;将内容翻译…

typescript递归处理

typescript是一种类型强约束的语言&#xff0c;一般来讲定义类型时都要明确指定类型的数据结构。而如果数据结构中涉及到不知道基层嵌套的递归时&#xff0c;就会有一些麻烦。 在 https://stackoverflow.com/questions/51657815/recursive-array-type-typescript 有一个回答…

Java Swing手搓坦克大战遇到的问题和思考

1.游戏中的坐标系颇为复杂 像素坐标系还有行列坐标&#xff0c;都要使用&#xff0c;这之间的互相转化使用也要注意 2.游戏中坦克拐弯的处理&#xff0c;非常重要 由于坦克中心点是要严格对齐到一条网格线&#xff0c;并沿着这条线前进的&#xff0c;如果拐弯不做处理&#…