Qt 6.5 类库实例大全:QObject

大家好,我是20YC小二!福利时间:欢迎(wx)扫码关注,免费领取《C++程序员入门必修第一课:C++基础课程》在线视频教程,还有更多技术分享!#下面进入今天内容#


1. QObject 介绍

QObject 是 Qt 库中最重要的类之一。作为所有 Qt 类的基类,QObject 提供了信号槽机制、对象树、动态属性、元对象系统、事件处理机制、线程安全、国际化等许多重要特性,这些特性可以帮助开发者轻松实现模块间通信、组件化、程序设计以及事件处理等方面的功能。

QObject 的主要功能和特点包括:

  • 信号槽机制:允许定义信号(signal)和槽(slot)来实现对象间的通信。一个信号可以连接到多个槽函数上,也可以将多个信号连接到同一个槽函数。
  • 对象树:支持管理对象树结构的方式,允许对象包含一个父对象和零个或多个子对象。当父对象被删除时,其所有子对象也会被自动销毁。
  • 动态属性:支持添加动态属性。除了一组已经存在的静态属性之外,每个对象实例还可以动态地创建和设置新的属性,这些属性不需要在编译器层面进行定义和声明。
  • 元对象系统:为每个 QObject 和其子类提供运行时类型信息,包括对象的类名、属性、方法和信号等信息,这些信息都可以在运行时被访问或者修改。
  • 事件处理机制:支持通过发送和接收事件来实现对象间的通信。Qt 中的事件是指某种对象发生的一些动作或状态变化,通常包含一个事件类型和一些参数。QObject 可以捕获并处理各种类型的事件,也可以派发事件给其他对象进行处理。
  • 线程安全:被设计为线程安全的基础构建单元。这意味着 QObject 默认可以在多线程环境下直接使用,而无需考虑同步问题。

QObject 是 Qt 框架的核心,提供了许多基础和关键的功能,可以帮助开发者更轻松、更高效地构建 Qt 应用程序。

  • 如何使用:

头文件:#include

cmake:find_package(Qt6 REQUIRED COMPONENTS Core)

target_link_libraries(mytarget PRIVATE Qt6::Core)

qmake:QT += core

  • QObject 派生类例子

#ifndef QOBJECTCHILDCLASS_H
#define QOBJECTCHILDCLASS_H
#include <QObject>    // 包含头文件

 // 继承于 QObject
class QObjectChildClass : public QObject
{
// 继承于 QObject 必须写的定义宏

    Q_OBJECT
public:
    // 构造函数
    explicit QObjectChildClass(QObject *parent = nullptr)
        : QObject{parent}
    {
    }

    void sendSignal(const QString& text)
    {
        // 发射一个信号
        emit sigDoSomething1(text);
    }
    
    // signals 用来修饰声明 QObjectChildClass 派生类的信号
signals:
    // 信号
    void sigDoSomething1(QString text);

     // slots 用来修改声明槽函数
private slots:
    void slotSomeFunction(int value) {}

};

#endif // QOBJECTCHILDCLASS_H

2. QObject 信号

// 当对象被销毁时,发射该信号。
void destroyed(QObject * obj = nullptr)
// 当对象名称修改时,发射该信号。
void objectNameChanged(const QString &objectName, QPrivateSignal)

3. QObject 基本属性

  • objectName 对象名称:
// 访问函数
QString objectName() const
void setObjectName(const QString &name)
  • isWidgetType 判断是否 Widget 对象:
// 访问函数
bool isWidgetType() const
  • isWindowType 判断是否 Window 对象:
// 访问函数
bool isWindowType() const
  • thread 对象线程

对象线程,简单理解就是信号槽函数在哪个线程上执行。

Qt 程序启动默认会创建一个主线程,用来处理主循环消息事件,所有继承于 QObject 类对象在创建时,如果没有指定线程,将默认跑在创建该对象的线程上,一般就是主线程。

// 返回对象所在的线程
QThread *QObject::thread() const
// 更改对象及其子对象的线程关联性。如果一个对象有父对象,则不能移动该对象到另一个线程中
void QObject::moveToThread(QThread *targetThread)
  • parent 父对象:
// 访问函数
QObject *parent()
void setParent(QObject *parent)

QObject 对象的销毁会自动销毁所有子对象:

#include <QObject>

// 子对象类
class QChildClass : public QObject
{
    Q_OBJECT
public:
    QChildClass(QObject* parent)
        QObject(parent)
    {}
};

// 父对象类
class QParentClass : public QObject
{
    Q_OBJECT
public:
    QParentClass(QObject* parent = nullptr)
        : QObject(parent)
    {}
};

QParentClass* pParentClass = new QParentClass();
// 创建子对象,指定父对象 pParentClass
QChildClass* pChildClass = new QChildClass(pParentClass);
// ...
delete pParentClass;    // 会自动销毁 pChildClass 子对象
//delete pChildClass;     // 在后面 delete 会导致  double free 异常
  • children 子对象列表:
// 返回对象所有子对象列表
const QObjectList &children() const
  • property 对象属性:

QObject 的 property 对象属性是一个超好用的功能,可以用来存储用户自定义数据,满足各种业务逻辑需求的开发。所有 QObject 派生类都可以使用该属性。

// 访问函数
bool setProperty(const char *name, const QVariant &value)
QVariant property(const char *name) const
QList<QByteArray> dynamicPropertyNames() const

/**** 例子 ****/
QParentClass* pParentClass = new QParentClass();
// 设置属性值
pParentClass->setProperty("user_id", QVariant(100));
// ...
// 取出属性值
int i_user_id = pParentClass->property("user_id").toInt();
// ...

4. connect() 连接函数

connect() 连接函数用于把 signal 信号和 slot 槽函数连接到一起,当 signal 信号发射时,slot 槽函数会响应执行。不再需要的连接需要用 disconnect() 断开。

注意事项:需要避免多次 QObject::connect 连接,否则会有一次发射信号,多次执行槽函数的风险。

  • connect() 例子:

#include <QWidget>
#include <QPushButton>

class QConnectSample : public QWidget
{
    Q_OBJECT
public:
    QConnectSample(QWidget* parent = nullptr)
        : QWidget(parent)
    {
        // 创建一个按钮
        m_pPushButton = new QPushButton("点击我", this);
        m_pPushButton->setGeometry(10, 10, 60, 32);

        // 连接按钮 clicked 点击事件
        QObject::connect(m_pPushButton, &QPushButton::clicked, this, &QConnectSample::slotPushButtonClicked);
    }
    ~QConnectSample()
    {
        QObject::disconnect(m_pPushButton, &QPushButton::clicked, this, &QConnectSample::slotPushButtonClicked);
    }

public Q_SLOTS:
    // 按钮点击处理函数
    void slotPushButtonClicked(bool checked = false)
    {
        // ...
    }

private:
    QPushButton * m_pPushButton = nullptr;
};
  • connect() 连接第五个参数:

一共有五种 connect 连接类型 Qt::ConnectionType:

// Qt::ConnectionType 这个枚举描述了在信号和槽之间的连接类型。
// 它决定一个特定信号被输送到槽函数,是立即执行,还是在放到队列排队执行。
// 五种连接类型如下:
enum ConnectionType {
    AutoConnection,            // (默认)自动根据信号发送的线程,与执行槽函数线程来选择
    DirectConnection,          // 立即执行
    QueuedConnection,          // 队列排队执行
    BlockingQueuedConnection,  // 与 Qt::QueuedConnection 相同,但会阻塞信号发送线程,直到槽函数执行返回
    UniqueConnection =  0x80   // 唯一标识;可以和以上任意连接类型组合,用按位或(|)。当设置了Qt::UniqueConnection,QObject::connect()函数如果连接已经存在(信号、槽函数和对象都相同),将返回失败。
};

5. deleteLater() 延迟销毁函数

调用 deleteLater() 函数不会立即销毁对象,而是在下一个主消息循环才自动销毁该对象,可以减少内存泄露和 double free 异常风险。

/**** 例子 ****/
QPushButton *p_push_button = new QPushButton(this);
// ...
// 当不需要的时候,调用 deleteLater 自动销毁对象
p_push_button->deleteLater();

6. QObject 事件处理

  • 事件接收器:

重写 QObject::event() 虚函数,用于接收对象事件,如果事件被处理,则返回 true

virtual bool event(QEvent *event)
  • 事件过滤器:

利用注册事件过滤器,可以捕捉处理指定对象事件。

// 注册事件过滤器
void installEventFilter(QObject *filterObj)
// 移除事件过滤器
void removeEventFilter(QObject *obj)

// 重写 QObject::eventFilter() 虚函数,用于接收注册过滤对象的事件;如果事件被处理,则返回 true
virtual bool eventFilter(QObject *watched, QEvent *event)

7. QObject 对象内置定时器

Qt 定时器的主要作用是定时执行特定的任务。它提供了简洁、易于使用的接口,使开发人员可以轻松创建和管理定时器对象。Qt 定时器能够提供高精度的计时能力,通常以毫秒级别为单位,以满足应用程序的需求。

  • 启动定时器函数:

/**
* @brief 启动定时器
* @param [in]int interval 定时器间隔时间,单位毫秒
* @param [in]Qt::TimerType timerType 定时器类型(精度)
*  - Qt::PreciseTimer    -> 精确的精度, 毫秒级
*  - Qt::CoarseTimer     -> 粗糙的精度, 和1毫秒的误差在5%的范围内, 默认精度
*  - Qt::VeryCoarseTimer -> 非常粗糙的精度, 精度在1秒左右
* @return 返回唯一定时器编号
**/
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
  • 杀死定时器函数:

/**
* @brief 杀死定时器
* @param [in]int id 定时器编号
* @return void
**/
void killTimer(int id)
  • 定时器处理函数:

// 重写 QObject::timerEvent 虚函数,用于处理定时器
virtual void timerEvent(QTimerEvent *event)
  • 定时器例子:

#include <QObject>
#include <QTimerEvent>

class QStartTimerSample : public QObject
{
    Q_OBJECT
public:
    QStartTimerSample(QObject* parent = nullptr)
        : QObject(parent)
    {
        // 启动1秒定时器;1000ms=1秒
        m_iTimerId = QObject::startTimer(1000, Qt::PreciseTimer);
    }
    ~QStartTimerSample()
    {
        // 杀死1秒定时器
        QObject::killTimer(m_iTimerId);
    }
private:
    // 定时器执行函数
    virtual void timerEvent(QTimerEvent *event)
    {
        if (event->timerId() == m_iTimerId)
        {
            // 1秒定时器ID
            // ...
        }

        QObject::timerEvent(event);
    }

private:
    int m_iTimerId = 0; // 1秒定时器ID
};

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

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

相关文章

RocketMq集成SpringBoot(待完善)

环境 jdk1.8, springboot2.7.3 Maven依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> <!-- lookup parent from…

C++学习笔记:继承

继承 什么是继承?继承的写法基类和派生类的赋值转换继承中的作用域派生类的默认成员函数单继承,多继承,虚拟继承is-a 和 has-a 什么是继承? 继承是C语言面向对象的三大特性之一&#xff0c;是面向对象程序设计使代码可以复用的最重要的手段,基本都是在一个类的基础上为了增加…

一个简单的可视化的A星自动寻路

一个简单的应用场景&#xff0c;流程图连线 源码&#xff1a; addExample("A星路径查找", function () {return {template: <div><div ref"main"></div></div>,data() { return {}; },computed: {},methods: {},mounted() {var c…

2-3、运算符

语雀原文链接 文章目录 1、算术运算符2、关系运算符3、逻辑运算符4、赋值运算符5、移位运算符6、位运算符(二进制位进行运算)7、条件运算符:三目运算符8、运算符的优先级 1、算术运算符 &#xff1a;加法-&#xff1a;减法*&#xff1a;乘法/&#xff1a;除法取商%&#xff1…

logback日志框架使用

依赖引入 <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version> </dependency> 使用logback日志框架只需要引入以上即可&#xff0c;(我们平时使用较多的Slf4j…

Fall in love with English

Fall in love with English 爱上英语 Hiding behind the loose dusty curtain, a teenager packed up his overcoat into the suitcase. 躲藏在布满尘土的松软的窗帘后边&#xff0c;一个年轻人打包他的外套到行李箱中。 He planned to leave home at dusk though there was th…

ssh免密登录及scp/rsync免密传输文件的方式

在通过ssh登录其它电脑或通过scp/rsync同其它电脑之间传输文件时&#xff0c;每次都需要输入密码&#xff0c;如下图所示&#xff1a;在windows10上通过ssh登录虚拟机&#xff0c;每次登录都需要输入密码&#xff1b;若端口默认为22,可省略通过-p指定 可通过将本机上的公钥key存…

熔池处理Tecplot 360 和CFD-Post做出一样的效果

熔池处理Tecplot 360 和CFD-Post做出一样的效果 效果展示详细讲述Tecplot 360实现过程分析实现过程第一步实现过程第二步界面美化注意点效果展示 详细讲述Tecplot 360实现过程 分析 这里主要是将体积分数大于0.5的区域抽取出来,然后显示温度场,所以这里主要考虑下面连个思考…

Agent相关工作调研

API Bank 要解决两个问题&#xff1a; 1)目前的LLM在使用工具方面的效果如何&#xff1f; 2) LLM使用工具还存在哪些障碍&#xff1f; 理想的效果&#xff1a;&#xff1a;通过访问全球工具存储库&#xff0c;LLM可以通过概述实现需求所需的所有步骤来帮助人们规划需求。随后…

你知道Java中的BigInteger类和BigDecimal类吗?

BigInteger和BigDecimal&#xff1a; 我们在学习JavaSE基础的时候学习过int和double&#xff0c;前者是整形&#xff0c;后者是双精度浮点数&#xff0c;但它们是有最大值的&#xff0c;也就是说&#xff0c;他两并不支持无限大的数字。 其范围如下所示&#xff1a; 因此对于…

图论-并查集

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图,求最小生成树Kruskal算法和最近公共祖先(LCA)等. 并查集的基本操作主要有: .1.初始化 2.查询find 3.合并union 一般我们都会采用路径压缩 这样…

Java期末复习题之分支循环

点击返回标题->23年Java期末复习-CSDN博客 第1题. 编写一个模拟同时掷骰子的程序。要用Math.random()模拟产生两个骰子&#xff0c;将两个结果相加&#xff0c;相加的和等于7的可能性最大&#xff0c;等于2和12的可能性最小。程序模投掷3600次&#xff0c;判断求和的结果是否…

在IDEA中创建Maven项目时没有src文件、不自动配置文件

错误示例&#xff1a; 没有src文件&#xff0c;并且没有自动下载相关的配置文件 对我这中情况无效的解决办法&#xff1a; ①配置好下列图中圈出来的文件 ②在VM选项中输入&#xff1a;“-DarchetypeInternal” ③点击应用&#xff0c;再点击确定 ④还是不行 解决办法&#x…

20 套监控平台统一成 1 套 Flashcat,国泰君安监控选型提效之路

author:宋庆羽-国泰君安期货 运维工作最重要的就是维护系统的稳定性&#xff0c;其中监控是保证系统稳定性很重要的一环。通过监控可以了解系统的运行状态&#xff0c;及时发现问题和系统隐患&#xff0c;有助于一线人员快速解决问题&#xff0c;提高业务系统的可用时长。 作为…

class064 Dijkstra算法、分层图最短路【算法】

class064 Dijkstra算法、分层图最短路【算法】 算法讲解064【必备】Dijkstra算法、分层图最短路 code1 743. 网络延迟时间 // Dijkstra算法模版&#xff08;Leetcode&#xff09; // 网络延迟时间 // 有 n 个网络节点&#xff0c;标记为 1 到 n // 给你一个列表 times&…

机器学习基本概念介绍 2023

笔记来源于&#xff1a; https://www.youtube.com/watch?vphQK8xZpgoU&t172s https://www.youtube.com/watch?vXLyPFnephpY&t645s Machine/Deep Learning 机器学习概况来说&#xff0c;让机器具备自动找函式的能力 &#xff08;Machine Learning 约等于 Looking …

MongoDB的条件操作符

本文主要介绍MongoDB的条件操作符。 目录 MongoDB条件操作符1.比较操作符2.逻辑操作符3.元素操作符4.数组操作符5.文本搜索操作符 MongoDB条件操作符 MongoDB的条件操作符主要分为比较操作符、逻辑操作符、元素操作符、数组操作符、文本搜索操作符等几种类型。 以下是这些操作…

unity Mesh Simplify 1.10(模型优化工具:查看面数,降低面数灯)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、面板参数详解说明二、使用方法总结 前言 有时候想对模型优化一下&#xff0c;奈何又不会建模方面的。虽然我感觉它的数值不大对&#xff0c;但是不影响我们优化顶点数嘛。 Me…

python 画条形图(柱状图)

目录 前言 基础介绍 月度开支的条形图 前言 条形图&#xff08;bar chart&#xff09;&#xff0c;也称为柱状图&#xff0c;是一种以长方形的长度为变量的统计图表&#xff0c;长方形的长度与它所对应的变量数值呈一定比例。 当使用 Python 画条形图时&#xff0c;通常会使…

0基础学java-day14-(集合)

一、集合 前面我们保存多个数据使用的是数组&#xff0c;那么数组有不足的地方&#xff0c;我们分析一下 1.数组 2 集合 数据类型也可以不一样 3.集合的框架体系 Java 的集合类很多&#xff0c;主要分为两大类&#xff0c;如图 &#xff1a;[背下来] package com.hspedu.c…