【Qt笔记】5.QWidget源码查阅

news2024/9/20 18:44:15

文章目录

  • 1 概述
  • 2 相关成员函数详解
    • 2.1 构造函数
    • 2.2 设置尺寸
    • 2.3 槽函数

1 概述

QWidget类是所有用户界面对象的基类。从QObject和QPaintDevice里继承过来

class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice

由上可以看出qt是把其封装成dll供外部接口调用。
我们在实际项目中使用QWidget会发现其调用到的头文件都是编译器的
形式如下:
D:\QT\5.14.2\mingw73_32\include\QtWidgets\qwidget.h

其实际的源码位置如下路径
D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qwidget.cpp

其中涉及的相关的文件有如下几个:

D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qtwidgetsglobal_p.h
D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qtwidgetsglobal.h
D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qwidget.cpp
D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qwidget_p.h
D:\QT\5.14.2\Src\qtbase\src\widgets\kernel\qwidget.h

在这里插入图片描述

2 相关成员函数详解

2.1 构造函数

看一个类我们大致都会从其构造函数出发。

QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
    : QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
    QT_TRY {
        d_func()->init(parent, f);
    } QT_CATCH(...) {
        QWidgetExceptionCleaner::cleanup(this, d_func());
        QT_RETHROW;
    }
}

这个代码有做异常处理.我们直接看init的操作即可。
init中传入父类的指针,并且传进去Qt::WindowFlags
该WindowFlags相关值如下: 可以直接看Qt助手里的描述
qt助手路径如下:
D:\QT\5.14.2\mingw73_32\bin\assistant.exe

ValueDescription
Qt::Widget是一个窗口或部件,有父窗口就是部件,没有就是窗口
Qt::Window是一个窗口,有窗口边框和标题
Qt::Dialog是一个对话框窗口
Qt::Sheet是一个窗口或部件Macintosh表单
Qt::Drawer是一个窗口或部件Macintosh抽屉,去掉窗口左上角的图标
Qt::Popup是一个弹出式顶层窗口
Qt::Tool是一个工具窗口
Qt::ToolTip是一个提示窗口,没有标题栏和窗口边框
Qt::SplashScreen是一个欢迎窗口,是QSplashScreen构造函数的默认值
Qt::Desktop是一个桌面窗口或部件
Qt::SubWindow是一个子窗口

init中会直接调用到

void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)

QWidget中的一些操作都是间接通过QWidgetPrivate去操作,去耦做的非常的规范.

在init中首先会创建QCoreApplication的instance

    if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
        qFatal("QWidget: Cannot create a QWidget without QApplication");

父类中插入

    Q_ASSERT(allWidgets);
    if (allWidgets)
        allWidgets->insert(q);

    int targetScreen = -1;
    if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
        const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(parentWidget);
        targetScreen = sw ? sw->screenNumber() : 0;
        parentWidget = 0;
    }

这是allWidgets的声明
QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid
操作完父类的一些赋值和插入后,需要设置一些相关的属性并传递相关事件

setAttribute()

分发事件

    QEvent e(QEvent::Create);
    QCoreApplication::sendEvent(q, &e);
    QCoreApplication::postEvent(q, new QEvent(QEvent::PolishRequest));

    extraPaintEngine = 0;

2.2 设置尺寸

最小尺寸获取

QSize QWidget::minimumSize() const
{
    Q_D(const QWidget);
    return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
}

最大尺寸的获取

QSize QWidget::maximumSize() const
{
    Q_D(const QWidget);
    return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
                 : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}

设置固定的尺寸,最大最小尺寸设置都是其中的一部分。

void QWidget::setFixedSize(int w, int h)
{
    Q_D(QWidget);
    bool minSizeSet = d->setMinimumSize_helper(w, h);
    bool maxSizeSet = d->setMaximumSize_helper(w, h);
    if (!minSizeSet && !maxSizeSet)
        return;

    if (isWindow())
        d->setConstraints_sys();
    else
        d->updateGeometry_helper(true);

    if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
        resize(w, h);
}

2.3 槽函数

仅仅举例关闭的槽函数

bool QWidget::close()
{
    return d_func()->close_helper(QWidgetPrivate::CloseWithEvent);
}

关闭的时候需要把相关的事件分发下去

   if (mode == CloseWithSpontaneousEvent)
            QApplication::sendSpontaneousEvent(q, &e);
        else
            QCoreApplication::sendEvent(q, &e);

...
//最后通过QCoreApplicationPrivate中的方法去销毁实例
            QCoreApplicationPrivate *applicationPrivate = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(QCoreApplication::instance()));
            applicationPrivate->maybeQuit();
...
//在其使用完后,正确设置相关的关闭属性,并销毁相关的对象
    if (!that.isNull()) {
        data.is_closing = 0;
        if (q->testAttribute(Qt::WA_DeleteOnClose)) {
            q->setAttribute(Qt::WA_DeleteOnClose, false);
            q->deleteLater();
        }
    }            

公共槽函数有如下:
在这里插入图片描述
同时QWidget提供了如下Signals,从名字可以看出其相关的发射情况

void customContextMenuRequested(const QPoint &pos)
void windowIconChanged(const QIcon &icon)
void windowTitleChanged(const QString &title)

而bool QWidget::event(QEvent *event)用来处理鼠标按建等其他相关事件的处理。

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

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

相关文章

vue2引入Element UI的详细步骤

目录 一、Element UI介绍 Element UI的特点&#xff1a; vue3引入Element plus的文章&#xff1a; 二、操作步骤 三、快速上手测试&#xff08;可做可不做&#xff09; 一、Element UI介绍 Element UI是一个基于Vue.js的组件库&#xff0c;提供了一套丰富、美观、易用的…

《类和对象》(下篇)

本文主要讲解类和对象的一些其他小知识。 文章目录 前情回顾一、用运算符重载写一个输入流和输出流①流插入②流提取③流提取和流插入的优化 二、const成员三、用运算符重载改变数组 1、再谈构造函数1.1 构造函数体赋值(不相当于初始化)1.2 初始化列表①引出初始化列表②怎么用…

GBDT+LR论文翻译

0.摘要 在线广告允许广告客户仅针对可衡量的用户响应进行出价和付费&#xff0c;例如广告点击。因此&#xff0c;点击预测系统是大多数在线广告系统的核心。伴随每日活跃用户超过7.5亿&#xff0c;活跃广告客户超过100万的情况&#xff0c;预测Facebook广告点击是一项具有挑战…

【题解】P4055 [JSOI2009] 游戏

link 题目大意 题目说得比较清楚。 题解 前置知识&#xff1a;二分图最大匹配、基础博弈论。 每个点只能走一次的四联通点阵&#xff0c;可以想到二分图匹配。 将其套路地奇偶分点&#xff0c;相邻两点连边&#xff08;显然不能为 #&#xff09;。 先求一个最大匹配。 …

单片机 0~10V 输出电路的实现

聊聊单片机实现 0~10V 输出电路的几种方案 ...... by 矜辰所致目录 前言一、MCU 的 DAC二、PWM 加滤波电路2.1 PWM 输出 DAC2.2 PWM 接滤波器的RC值选择说明2.3 0~ 3.3V PWM 输出 0 ~10V方案一&#xff1a;RC 滤波器方案二&#xff1a;三极管 三、专用转换芯片结语 前言 好…

操作系统(3.1)--处理机调度和作业

目录 一、处理机调度层次 1.高级调度(High Level Scheduling) 2.低级调度&#xff08;Low Level Scheduling) 3.中级调度(Intermediate Scheduling) 二、处理机调度算法的目标 1.处理机调度算法的共同目标 2.批处理系统的目标 3.分时系统的目标 三、批处理系统中的作业…

【k8s完整实战教程3】k8s集群部署kubesphere

系列文章&#xff1a;这个系列已完结&#xff0c;如对您有帮助&#xff0c;求点赞收藏评论。 读者寄语&#xff1a;再小的帆&#xff0c;也能远航&#xff01; 【k8s完整实战教程0】前言【k8s完整实战教程1】源码管理-Coding【k8s完整实战教程2】腾讯云搭建k8s托管集群【k8s完…

【C++】海量数据面试题

海量数据面试题 文章目录 海量数据面试题一、哈希切割二、位图应用1.给定100亿个整数&#xff0c;设计算法找到只出现一次的整数2.求两个文件交集3.在100亿个整数中找到出现次数不超过2次的所有整数 三、布隆过滤器1.求两文件交集&#xff08;近似算法&#xff09;2.求两文件交…

气传导和骨传导耳机哪个好?简单科普这两种蓝牙耳机

在生活中&#xff0c;我们经常会用到耳机&#xff0c;特别是在日常娱乐听歌、运动休闲、户外通勤的时候&#xff0c;一款舒适的耳机是必不可少的。 而最近几年&#xff0c;随着科技的发展&#xff0c;各大品牌也相继推出了各种类型的耳机&#xff0c;其中比较热门的就有气传导…

如何在电脑上使用wink一键高清优化短视频画质

如何在电脑上使用wink一键高清优化短视频画质 文章目录 如何在电脑上使用wink一键高清优化短视频画质1.软件简介1.1痛点1.2解决方案 2.实际操作2.1准备工作2.1.1下载雷电模拟器2.1.2下载wink 2.2.安装软件2.2.1安装雷电模拟器2.2.2在雷电模拟器中安装wink 2.3雷电模拟器基本设置…

软件测试实验:Junit单元测试

目录 前言 实验目的 实验内容 实验要求 实验过程 题目一 题目一测试结果 题目二 题目二实验结果 总结 前言 软件测试是软件开发过程中不可缺少的一个环节&#xff0c;它可以保证软件的质量和功能&#xff0c;发现并修复软件的缺陷和错误。软件测试分为多种类型&…

《数据结构》---术语篇

目录 前言: 一.术语 1.1数据 1.2数据结构 1.3逻辑结构和物理结构 二.数据类型和抽象数据类型 ​​​​​​​ ❤博主CSDN&#xff1a;啊苏要学习 ▶专栏分类&#xff1a;数据结构◀ 学习数据结构是一件有趣的事情&#xff0c;希望读者能在我的博文切实感受到&#xff0c…

Numpy从入门到精通——随机生成数组|特定生成数组|规则生成数组

这个专栏名为《Numpy从入门到精通》&#xff0c;顾名思义&#xff0c;是记录自己学习numpy的学习过程&#xff0c;也方便自己之后复盘&#xff01;为深度学习的进一步学习奠定基础&#xff01;希望能给大家带来帮助&#xff0c;爱睡觉的咋祝您生活愉快&#xff01; 这一篇介绍《…

Qt内存管理及泄露后定位到内存泄漏位置的方法

Qt内存管理机制 Qt使用对象父子关系进行内存管理。在创建类的对象时&#xff0c;为对象指定父对象指针。当父对象在某一时刻被销毁释放时&#xff0c;父对象会先遍历其所有的子对象&#xff0c;并逐个将子对象销毁释放。 Qt内存管理代码示例 QLabel *label new QLabel;这里…

【==是判断相等吗?---错辣】C++和JAVA中判断字符串值相等的区别

文章目录 先上结论C中stringJAVA中String回顾结论 参考文章&#xff1a;这里&#xff1b;这里&#xff1b;这里 先上结论 C中的string类型可以使用和!来判断两个字符串的值是否相等&#xff1b;而JAVA不行&#xff0c;JAVA中和!是用来判断两个字符串的地址是否相同&#xff08…

c++学习之类与对象3

目录 成员变量和函数的存储 this指针 this指针的工作原理 this指针的应用 const修饰的成员函数 友元 友元的语法 1.普通全局函数成为类的友元 2.类的某个成员函数作为另一个类的友元 整个类作为另一个类的友元 运算符重载 1 运算符重载的基本概念 2 重载加号运算符…

MySQL数据库学习笔记之存储引擎

存储引擎 MySQL体系结构 连接层 最上层是一些客户端和连接服务&#xff0c;主要完成一些类似于连接处理、授权认证、以及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 服务层 第二层架构主要完成大多数的核心服务功能&#xff0c;如SQL接口&am…

【JavaScript】6.DOM

文章目录 DOM1. 简介2. 获取元素2.1 根据 ID 获取2.2 根据标签名获取2.3 通过 HTML5 新增的方法获取2.4 特殊元素获取 3. 事件基础3.1 事件概述3.2 事件三要素3.3 执行事件步骤 DOM 1. 简介 文档对象模型&#xff08;Document Object Model&#xff0c;简称 DOM&#xff09;&…

web自动化测试框架落地实施全过程-测试环境搭建 (Selenium+Python)

一、什么是web自动化测试? Web自动化测试是指使用自动化工具模拟用户在Web浏览器中执行的操作&#xff0c;通过编写脚本来自动化执行测试用例&#xff0c;以验证Web应用程序的功能、性能和兼容性等方面的质量。其主要目的是降低测试成本和时间&#xff0c;并提高测试效率和准…

LDAP未授权漏洞验证

因为工作需要&#xff0c;这里验证了下LDAP未授权。 以下是收集到的资料&#xff0c;最后是具体使用&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 更新 2&#xff09;连接ad域有两个地址&#xff1a; ldap://http://XXXXX.com:389 和 ldap://http://XXXXX.…