QT6 源(45):分隔条 QSplitter 允许程序的用户修改布局,程序员使用 IDE时,就是分隔条的用户,以及其 QSplitter 源代码

news2025/4/26 14:47:38

(1)

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

(2)本类的继承关系如下,所以说分隔条属于容器

在这里插入图片描述

(3)本类的属性

在这里插入图片描述

(4) 这是一份 QSplitter 的举例代码,注意其构造函数时候的传参

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QHBoxLayout * horizontalLayout;
    QSplitter   * splitter;
    QFrame      * frame;
    QFrame      * frame_2;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
            
        Widget->resize(523, 339);
        
        horizontalLayout = new QHBoxLayout(Widget); //为主窗体采用水平布局
        horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
        
        splitter = new QSplitter(Widget); //对,生成的是水平分隔条。本分割条属于本窗体容器。
        splitter->setObjectName(QString::fromUtf8("splitter"));
        splitter->setOrientation(Qt::Horizontal);
        
        frame = new QFrame(splitter);
        frame->setObjectName(QString::fromUtf8("frame"));
        frame->setFrameShape(QFrame::StyledPanel);
        frame->setFrameShadow(QFrame::Plain);
        frame->setLineWidth(2);
        splitter->addWidget(frame); //把左 frame 添加入 splitter
        //继承关系上, splitter 才扩充了添加窗体的方法
        
        frame_2 = new QFrame(splitter);
        frame_2->setObjectName(QString::fromUtf8("frame_2"));
        frame_2->setFrameShape(QFrame::StyledPanel);
        frame_2->setFrameShadow(QFrame::Plain);
        frame_2->setLineWidth(2);
        splitter->addWidget(frame_2); //把右 frame 添加入 splitter

        horizontalLayout->addWidget(splitter); //把分隔条 splitter 添加到主窗体的布局中
              //可见,分隔条相当于容器,隐身的容器;也相当于布局,可以接收子容器,还可以被放入布局中
        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

(5)给出源代码,来自于头文件 qsplitter . h

#ifndef QSPLITTER_H
#define QSPLITTER_H

#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qframe.h>
#include <QtWidgets/qsizepolicy.h>


/*
QT_CONFIG宏实现了对 Qt特性的安全编译时检查。特性可以处于三种状态:
0 或未定义:在测试时会引发编译错误
-1:该功能不可用
1:该功能可用
    The QT_CONFIG macro implements a safe compile time check for features of Qt.
    Features can be in three states:
        0 or undefined: This will lead to a compile error when testing for it
        -1: The feature is not available
        1: The feature is available
*/
#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)

#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1,\
 "Required feature " #feature " for file " __FILE__ " not available.")

QT_REQUIRE_CONFIG(splitter); //条件编译,确保有了此源代码模块

QT_BEGIN_NAMESPACE  //说明本类定义在 QT 的全局空间

class QSplitterPrivate;
class QTextStream;

class QSplitterHandle;

//    class QLayout : public QObject, public QLayoutIte
//    class QWidget : public QObject, public QPaintDevice
//class QFrame : public QWidget
//一个分割器允许用户通过拖动它们之间的边界来控制子控件的大小。
//任何数量的控件都可以由一个单一的分割器控制。
//如果在调用 insertWidget()或addWidget()时,一个部件已经在 QSplitter中,
//它将移动到新位置。这可以用于稍后重新排序 splitter中的部件。
//可以使用indexOf()、widget()和count()来访问splitter 中的部件。
//默认的QSplitter将其子元素水平排列(并排);
//您可以使用setOrientation(Qt::Vertical)将其子元素垂直排列。
//默认情况下,所有小部件都可以像用户希望的那样大或小,
//介于小部件的minimumSizeHint()(或minimumSize())和maximumSize()之间。
//默认情况下,QSplitter会动态调整其子项的大小。
//如果您希望QSplitter仅在调整大小操作结束时调整子项的大小,请调用setOpaqueResize(false)。
//小部件之间初始大小的分布是通过将初始大小与拉伸因子相乘来确定的。
//您还可以使用setSizes()来设置所有小部件的大小。函数sizes()返回由用户设置的大小。
//或者,您可以使用saveState()和restoreState()分别保存和恢复小部件的大小。
//当你隐藏(hide)一个子元素时,它的空间将被分配到其他子元素中。当你再次显示(show)它时,它将被恢复。
class Q_WIDGETS_EXPORT QSplitter : public QFrame
{
    Q_OBJECT //又插入了此宏

    //此属性保存了分割器的方向.
    //默认情况下,方向是水平(即小部件是并排排列的)。可能的方向是Qt::Horizontal和Qt::Vertical。
    Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)

    //如果分隔条在交互式移动时动态(不透明)地重新调整大小,则返回true。否则返回 false。
    //默认的缩放行为取决于样式(由SH_Splitter_OpaqueResize样式提示确定)。
    //但是,您可以通过调用setOpaqueResize()来覆盖它。
    Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize)//不透明

    //此属性包含分隔符手柄的宽度。即被分隔条隔开的内部各控件之间的间距。
    //默认情况下,此属性包含一个值,该值取决于用户的平台和样式偏好。
    //如果您将 handleWidth 设置为1或0,则实际抓取区域将增长到与其各自的小部件重叠几个像素
    Q_PROPERTY(int handleWidth READ handleWidth WRITE setHandleWidth)

    //这个属性表示子控件是否可以被用户缩小到0的大小。默认情况下,子元素是可折叠的。
    //使用setCollapsible()方法可以启用或禁用单个子元素的折叠。
    Q_PROPERTY(bool childrenCollapsible //倒塌;垮塌;可折叠 collapse
               READ childrenCollapsible WRITE setChildrenCollapsible)

private:
    Q_DISABLE_COPY(QSplitter)
    Q_DECLARE_PRIVATE(QSplitter)
private:
    friend class QSplitterHandle;

public:
    //构造一个水平分割器,将 parent参数传递给 QFrame构造函数。
    explicit QSplitter(QWidget * parent = nullptr); //本组件属于 parent容器
    explicit QSplitter(Qt::Orientation, QWidget * parent = nullptr);
    //Constructs a splitter with the given orientation and parent.

    ~QSplitter();

//Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
    Qt::Orientation orientation() const;
    void         setOrientation(Qt::Orientation); //方向就是水平或垂直两种

//Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize)
    bool    opaqueResize() const;
    void setOpaqueResize(bool opaque = true);

//Q_PROPERTY(int handleWidth READ handleWidth WRITE setHandleWidth)
    int     handleWidth() const;
    void setHandleWidth(int);

//Q_PROPERTY(bool childrenCollapsible
//           READ childrenCollapsible WRITE setChildrenCollapsible)
    bool    childrenCollapsible() const;
    void setChildrenCollapsible(bool);

    //Returns true if the widget at index is collapsible, otherwise returns false.
    bool  isCollapsible(int index) const;
    void setCollapsible(int index, bool);
    //Sets whether the child widget at index is collapsible to collapse.
    //默认情况下,子项是可折叠的,这意味着用户可以将它们的大小缩小到大小0,
    //即使它们具有非零的minimumSize()或minimumSizeHint()。
    //可以通过调用此函数在每个 widget的基础上更改此行为,
    //也可以通过设置 childrencollapsible 属性为拆分器中的所有 widget 全局更改此行为。

    //返回此拆分器中所有小部件的大小参数的列表。
    //如果拆分器的方向是水平,则列表包含从左到右的像素宽度;
    //如果方向是垂直的,则列表包含从顶部到底部的像素高度。
    //将值传递给另一个分块器的 setSizes()函数将产生一个布局与此相同的分块器。
    QList<int>   sizes() const; //本函数的返回值是一个链表容器
    void      setSizes(const QList<int> &list);
    //将子控件的相应大小设置为列表中给出的值。
    //如果分隔线是水平的,则值以像素为单位设置每个小部件的宽度,从左到右。
    //如果分隔线是垂直的则设置每个小部件的高度,从上到下。
    //列表中的额外值将被忽略。如果列表包含太少的值,结果是不确定的,但程序仍然会表现得很好。
    //分割器组件的整体大小不受影响。相反,任何额外的/缺失的空间将根据尺寸的相对权重在组件之间分配。
    //如果您指定大小为0,则小部件将不可见。
    //小部件的大小策略将被保留。也就是说小于相应小部件的最小大小提示值的值将被提示值替换。

    //保存分割器的布局状态。
    //通常,这用于与QSettings一起使用,以记住未来会话的大小。版本号作为数据的一部分存储。
    QByteArray    saveState() const;
    bool       restoreState(const QByteArray &state);
    //Restores the splitter's layout to the state specified.
    //Returns true if the state is restored; otherwise returns false.

    QSize        sizeHint() const override;
    QSize minimumSizeHint() const override;

    //Returns the valid range of the splitter at index in *min and *max
    //if min and max are not 0.
    void getRange(int index, int *min, int *max) const;

    //Returns the number of widgets contained in the splitter's layout.
    int count() const;

    int indexOf(QWidget *w) const;
    QWidget *        widget(int index) const; //!!扩充了添加窗体的方法,就类似于 Qlayout了
    void          addWidget(QWidget *widget);
    void       insertWidget(int index, QWidget *widget);
    QWidget * replaceWidget(int index, QWidget *widget);

    void refresh(); //不要调用本函数
    //Updates the splitter's state. You should not need to call this function.

    //Updates the size policy of the widget at position index to
    //have a stretch factor of stretch.
    //stretch 并不是有效的拉伸因子;有效的拉伸因子是通过取小部件的初始大小并
    //将其乘以 stretch 计算得出的  。
    void setStretchFactor(int index, int stretch);

    //返回分割器布局中给定索引处左侧(或上方)的项的句柄,
    //如果不存在这样的项则返回nullptr。索引为0的句柄总是隐藏的。
    //对于像阿拉伯语和希伯来语这样的右至左语言,水平分隔符的布局是颠倒的。在索引处的控件右侧是手柄。
    QSplitterHandle         *       handle(int index) const;
protected:
    virtual QSplitterHandle * createHandle();
    //返回一个新的分隔符处理程序作为此分隔符的子控件。
    //此函数可以在子类中重新实现,以提供对自定义处理程序的支持。

    bool       event(QEvent *) override;
    void  childEvent(QChildEvent *) override;
    void resizeEvent(QResizeEvent *) override;
    void changeEvent(QEvent *) override;

    //在位置 pos 显示橡皮筋 RubberBand。如果 pos是负数,则移除皮筋。
    void setRubberBand(int position);

    int  closestLegalPosition(int pos, int index);
    //Returns the closest legal position to pos of the widget at index.
    //对于阿拉伯语和希伯来语等从右向左的语言,水平分隔符的布局
    //是颠倒的。然后从小部件的右边缘测量位置。

    //将分割器手柄的左边缘或顶部边缘在索引 index 处移动到尽可能靠近位置pos的位置,
    //位置pos是从小部件的左边缘或顶部边缘的距离。
    void moveSplitter(int pos, int index);

Q_SIGNALS: //信号函数
    void     splitterMoved(int pos, int index);
    //当 index 索引处的分路器手柄移动到位置 pos 时,会发出此信号。
}; //完结 class QSplitter : public QFrame


class QSplitterHandlePrivate;

//当人们想到分割器时,通常会想到QSplitterHandle。它是用于调整部件大小的控制柄。
//使用 QSplitter的典型开发人员永远不必担心 QSplitterHandle。
//它提供给那些想要提供额外功能(如弹出菜单)的分割器处理程序的开发人员。
//创建分割器处理程序的典型方法是子类化QSplitter,然后重写QSplitter::createHandle()以
//实例化自定义分割器处理程序。
class Q_WIDGETS_EXPORT QSplitterHandle : public QWidget
{
    Q_OBJECT
public:
    explicit QSplitterHandle(Qt::Orientation o, QSplitter *parent);
    ~QSplitterHandle();

    void setOrientation(Qt::Orientation o);
    Qt::Orientation orientation() const;
    bool opaqueResize() const;
    QSplitter *splitter() const;

    QSize sizeHint() const override;

protected:
    void paintEvent(QPaintEvent *) override;
    void mouseMoveEvent(QMouseEvent *) override;
    void mousePressEvent(QMouseEvent *) override;
    void mouseReleaseEvent(QMouseEvent *) override;
    void resizeEvent(QResizeEvent *) override;
    bool event(QEvent *) override;

    void moveSplitter(int p);
    int closestLegalPosition(int p);

private:
    Q_DISABLE_COPY(QSplitterHandle)
    Q_DECLARE_PRIVATE(QSplitterHandle)
};

QT_END_NAMESPACE

#endif // QSPLITTER_H

(6)

谢谢

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

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

相关文章

Huffman(哈夫曼)解/压缩算法实现

一、文件压缩 哈夫曼压缩算法需要对输入的文件&#xff0c;逐字节扫描&#xff0c;统计出不同字节出现的数量&#xff08;频率&#xff09;&#xff0c;根据的得到的频率生成一组叶子节点&#xff0c;这些节点存储着<字节信息>和<频率>,通常需要按频率排序后存储在…

迭代器模式:统一数据遍历方式的设计模式

迭代器模式&#xff1a;统一数据遍历方式的设计模式 一、模式核心&#xff1a;将数据遍历逻辑与数据结构解耦 在软件开发中&#xff0c;不同的数据结构&#xff08;如数组、链表、集合&#xff09;有不同的遍历方式。如果客户端直接依赖这些数据结构的内部实现来遍历元素&…

LeetCode每日一题4.23

题目 问题分析 计算每个数字的数位和&#xff1a;对于从 1 到 n 的每个整数&#xff0c;计算其十进制表示下的数位和。 分组&#xff1a;将数位和相等的数字放到同一个组中。 统计每个组的数字数目&#xff1a;统计每个组中有多少个数字。 找到并列最多的组&#xff1a;返回数…

RunnerGo API性能测试实战与高并发调优

API 性能测试通过模拟不同负载场景&#xff0c;量化评估 API 的响应时间、吞吐量、稳定性、可扩展性等性能指标&#xff0c;关注其在正常、高峰甚至极限负载下的表现。这有助于确保 API 稳定高效地运行&#xff0c;为调用者提供优质服务。 接下来&#xff0c;我们借助 RunnerG…

STM32——相关软件安装

本文是根据江协科技提供的教学视频所写&#xff0c;旨在便于日后复习&#xff0c;同时供学习嵌入式的朋友们参考&#xff0c;文中涉及到的所有资料也均来源于江协科技&#xff08;资料下载&#xff09;。 Keil5 MDK安装 1.安装Keil5 MDK2.安装器件支持包方法一&#xff1a;离线…

数据结构入门【算法复杂度】超详解深度解析

&#x1f31f; 复杂度分析的底层逻辑 复杂度是算法的"DNA"&#xff0c;它揭示了两个核心问题&#xff1a; 数据规模(n)增长时&#xff0c;资源消耗如何变化&#xff1f; 不同算法在极端情况下的性能差异有多大&#xff1f; 数学本质解析 复杂度函数 T(n)O(f(n))…

java多线程(7.0)

目录 ​编辑 定时器 定时器的使用 三.定时器的实现 MyTimer 3.1 分析思路 1. 创建执行任务的类。 2. 管理任务 3. 执行任务 3.2 线程安全问题 定时器 定时器是软件开发中的一个重要组件. 类似于一个 "闹钟". 达到一个设定的时间之后, 就执行某个指定好的…

Long类型封装Json传输时精度丢失问题

在信息做传输时&#xff0c;经常会使用到类型转换&#xff0c;这个时候因为一些问题会导致精度的丢失。在支付业务中这种问题更为致命。 这里我主动生成一个支付订单并将相关信息使用base64编码为一个二维码返回给前端进行支付&#xff0c;前端进行支付时我通过回调方法发现回调…

《从GPT崛起,看AI重塑世界》

《从GPT崛起,看AI重塑世界》 GPT 诞生:AI 领域的震撼弹 2022 年 11 月 30 日,OpenAI 发布了一款名为 ChatGPT 的人工智能聊天机器人程序,宛如一颗重磅炸弹投入了平静的湖面,迅速在全球范围内引发了轩然大波,成为了科技领域乃至大众舆论场中最热门的话题之一。一时间,无…

系统架构-安全架构设计

概述 对于信息系统来说&#xff0c;威胁有&#xff1a;物理环境&#xff08;最基础&#xff09;、通信链路、网络系统、操作系统、应用系统、管理系统 物理安全&#xff1a;系统所用设备的威胁&#xff0c;如自然灾害、电源故障通信链路安全&#xff1a;在传输线路上安装窃听…

鼠标指定范围内随机点击

鼠标指定范围内随机点击 点赞神器 将鼠标移动到相应位置后按F5 F6键&#xff0c;设置点击范围&#xff0c; F8开始&#xff0c;ESC中止。 有些直播有点赞限制&#xff0c;例如某音&#xff0c;每小时限制3千次&#xff0c;可以设置1200毫秒&#xff0c;3000次。 软件截图&#…

HashSet 概述

1. HashSet 概述 HashSet 是 Java 集合框架中 Set 接口的一个实现类&#xff0c;它存储唯一元素&#xff0c;即集合中不会有重复的元素。HashSet 基于哈希表&#xff08;实际上是 HashMap 实例&#xff09;来实现&#xff0c;不保证元素的顺序&#xff0c;并且允许存储 null 元…

遥测终端机,推动灌区流量监测向数据驱动跃迁

灌区范围那么大&#xff0c;每一滴水怎么流都关系到粮食够不够吃&#xff0c;还有生态能不能平衡。过去靠人工巡查、测量&#xff0c;就像拿着算盘想算明白大数据&#xff0c;根本满足不了现在水利管理的高要求。遥测终端机一出现&#xff0c;就像给灌区流量监测安上了智能感知…

蓝耘平台介绍:算力赋能AI创新的智算云平台

一、蓝耘平台是什么 蓝耘智算云&#xff08;LY Cloud&#xff09;是蓝耘科技打造的现代化GPU算力云服务平台&#xff0c;深度整合自研DS满血版大模型技术与分布式算力调度能力&#xff0c;形成"模型算力"双轮驱动的技术生态。平台核心优势如下&#xff1a; 平台定位…

QtDesigner中Button控件详解

一&#xff1a;Button控件 关于Button控件的主要作用就是作为触发开关&#xff0c;通过点击事件&#xff08;click&#xff09;执行代码逻辑&#xff0c;或者作为功能入口&#xff0c;跳转到其他界面或模块。 二&#xff1a;常见属性与配置 ①Button的enabled&#xff0c;大…

Flink 源码编译

打包命令 打包整个项目 mvn clean package -DskipTests -Drat.skiptrue打包单个模块 mvn clean package -DskipTests -Drat.skiptrue -pl flink-dist如果该模块依赖其他模块&#xff0c;可能需要先将其他模块 install 到本地&#xff0c;如果依赖的模块的源代码有修改&#…

docker的安装和简单使用(ubuntu环境)

环境准备 这里用的是linux的环境&#xff0c;如果没有云服务器的话&#xff0c;就是用虚拟环境吧。 虚拟环境的安装参考&#xff1a;vmware17的安装 linux镜像的安装 docker安装 我使用的是ubuntu&#xff0c;使用以下命令&#xff1a; 更新本地软件包索引 sudo apt u…

EasyRTC音视频实时通话在线教育解决方案:打造沉浸式互动教学新体验

一、方案概述 EasyRTC是一款基于WebRTC技术的实时音视频通信平台&#xff0c;为在线教育行业提供了高效、稳定、低延迟的互动教学解决方案。本方案将EasyRTC技术深度整合到在线教育场景中&#xff0c;实现师生间的实时音视频互动等核心功能&#xff0c;打造沉浸式的远程学习体…

【分布式系统中的“瑞士军刀”_ Zookeeper】一、Zookeeper 快速入门和核心概念

在分布式系统的复杂世界里&#xff0c;协调与同步是确保系统稳定运行的关键所在。Zookeeper 作为分布式协调服务的 “瑞士军刀”&#xff0c;为众多分布式项目提供了高效、可靠的协调解决方案。无论是在分布式锁的实现、配置管理&#xff0c;还是在服务注册与发现等场景中&…

Electron从入门到入门

项目说明 项目地址 项目地址&#xff1a;https://gitee.com/ruirui-study/electron-demo 本项目为示例项目&#xff0c;代码注释非常清晰&#xff0c;给大家当做入门项目吧。 其实很多东西都可以在我这基础上添加或修改、市面上有些已开源的项目&#xff0c;但是太臃肿了&am…