QT布局管理(分割窗口QSplitter类、停靠窗口QDockWidget类、堆栈窗体QStackedWidget类、基本布局QLayout)

此片文章简单介绍布局管理的使用方法。通过实例先分别介绍分隔窗口QSplitter类、停靠窗口QDockWidget类及QStackedWidget类的使用,最后再通过一个实例介绍QLayout的使用。

分割窗口QSplitter类

分隔窗口可以灵活地布局窗口,可以用在文件资源管理器地窗口设计中。下图显示一个简单的分割窗口功能,界面窗口由3个子窗口组成,各个窗口之间可随意拖拽改变大小。
在这里插入图片描述
上图为spliter工程运行效果,相关代码如下:

int main(int argc, char* argv[])
{QApplication a(argc, argv);QFont font("ZYSong18030", 12);                               //指定显示字体a.setFont(font);//主分割窗口QSplitter* splitterMain = new QSplitter(Qt::Horizontal, 0);QTextEdit* textLeft = new QTextEdit(QObject::tr("Left Widget"), splitterMain);textLeft->setAlignment(Qt::AlignCenter);//右部分分割窗口QSplitter* splitterRight = new QSplitter(Qt::Vertical, splitterMain);splitterRight->setOpaqueResize(false);QTextEdit* textUp = new QTextEdit(QObject::tr("Top Widget"), splitterRight);textUp->setAlignment(Qt::AlignCenter);QTextEdit* textBottom = new QTextEdit(QObject::tr("Bottom Widget"), splitterRight);textBottom->setAlignment(Qt::AlignCenter);splitterMain->setStretchFactor(1, 1);splitterMain->setWindowTitle(QObject::tr("Splitter"));splitterMain->show();//spliter w;//w.show();return a.exec();
}

关键代码说明如下:

  • QSplitter* splitterMain = new QSplitter(Qt::Horizontal, 0):创建QSplitter对象,并设置水平分隔窗口。
  • QTextEdit* textLeft = new QTextEdit(QObject::tr(“Left Widget”), splitterMain):新建QTextEdit对象并插添加到主分割窗口中。
  • QSplitter* splitterRight = new QSplitter(Qt::Vertical, splitterMain):新建一个QSplitter对象设置为垂直分割并添加到父窗口。
  • splitterRight->setOpaqueResize(false):设定分割窗口的分割线在拖拽时是否为实时更新显示,true则实时更新显示,false则在拖拽时只显示一条灰色的粗线条。
  • splitterMain->setStretchFactor(1, 1):此方法用于设定可伸缩控件,第一个参数指定设置的控件序号,空间序号按插入顺序从0开始编号;第二个参数大于0表示此控件为可伸缩控件。此实例中设定右边的分割窗口为可伸缩控件,当整个对话框的宽度发生变化,左边的文本编辑框宽度保持不变,右边的分割窗口宽度随调整个对话框大小的改变进行调整。

停靠窗口QDockWidget类

以下是设置QDockWidget停靠窗口的一般流程:

  1. 创建QDockWidget对象的停靠窗口。
  2. 设置此停靠窗口的属性,通常调用setFeatures和setAllowedAreas两个方法。
  3. 新建一个要插入停靠窗口的控件。
  4. 将控件插入停靠窗口,调用setWidget方法。
  5. 使用addDockWidget方法在QMainWindow中加入此停靠窗体。

DockWindows工程运行的QDockWidget停靠窗口如下图所示:窗口1只可在主窗口的左边和右边停靠;窗口2只可在浮动窗口和右部停靠两种状态间切换,并且不可移动;窗口3可实现停靠窗口的各种状态。
在这里插入图片描述
界面布局核心代码如下:

DockWindows::DockWindows(QWidget *parent): QMainWindow(parent)
{setWindowTitle(tr("DockWindows"));	//设置主窗口的标题栏文字QTextEdit* te = new QTextEdit(this);	//定义一个QTextEdit对象作为主窗口te->setText(tr("Main Window"));te->setAlignment(Qt::AlignCenter);setCentralWidget(te);          		//将此编辑框设为主窗口的中央窗体//停靠窗口1QDockWidget* dock = new QDockWidget(tr("DockWindow1"), this);//可移动dock->setFeatures(QDockWidget::DockWidgetMovable);dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);QTextEdit* te1 = new QTextEdit();te1->setText(tr("Window1,The dock widget can be moved between docks by the user" ""));dock->setWidget(te1);addDockWidget(Qt::RightDockWidgetArea, dock);//停靠窗口2dock = new QDockWidget(tr("DockWindow2"), this);dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable); //可关闭、可浮动QTextEdit* te2 = new QTextEdit();te2->setText(tr("Window2,The dock widget can be detached from the main window,""and floated as an independent window, and can be closed"));dock->setWidget(te2);addDockWidget(Qt::RightDockWidgetArea, dock);//停靠窗口3dock = new QDockWidget(tr("DockWindow3"), this);dock->setFeatures(QDockWidget::AllDockWidgetFeatures);   //全部特性QTextEdit* te3 = new QTextEdit();te3->setText(tr("Window3,The dock widget can be closed, moved, and floated"));dock->setWidget(te3);addDockWidget(Qt::RightDockWidgetArea, dock);
}

其中有两个方法需要我们关注一下:

  • setFeatures:此方法用于设置停靠窗口的特性,函数声明如下:
    void setFeatures(QDockWidget::DockWidgetFeatures features)
    参数QDockWidget::DockWidgetFeatures指定停靠窗体的特性,包括以下几种参数。
    • QDockWidget::DockWidgetClosable:停靠窗口可关闭。
    • QDockWidget::DockWidgetMovable:停靠窗体可移动。
    • QDockWidget::DockWidgetFloatable:停靠窗体可浮动。
    • QDockWidget::DockWidgetVerticalTitleBar:dock小部件在左侧显示一个垂直的标题栏。这可以用来增加QMainWindow中的垂直空间。
    • QDockWidget::NoDockWidgetFeatures:不可移动、不可关闭、不可浮动。
  • setAllowedAreas:从方法用于设置停靠窗体可停靠的区域,函数声明如下:
    void setAllowedAreas(Qt::DockWidgetAreas areas)
    参数Qt::DockWidgetAreas指定停靠窗口可停靠区域,包括以下几种参数。
    • Qt::LeftDockWidgetArea:可在主窗口的左侧停靠。
    • Qt::RightDockWidgetArea:可在主窗口的右侧停靠。
    • Qt::TopDockWidgetArea:可在主窗口的顶部停靠。
    • Qt::BottomDockWidgetArea:可在主窗口的底部停靠。
    • Qt::AllDockWidgetAreas:可在主窗口的(以上四个)部位停靠。
    • Qt::NoDockWidgetArea:只可停靠在插入处。

堆栈窗体QStackedWidget类

堆栈窗体QStackedWidget在实际应用中,经常与列表框QListWidget及下拉列表框QComboBox配合使用。
堆栈窗体QStackedWidget类的使用,当选择左侧列表框中不同的选项时,右侧显示所选的不同的窗体。效果图如下所示。
在这里插入图片描述
StackedWidget项目关键代码如下:

StackedWidget::StackedWidget(QWidget *parent): QDialog(parent)
{setWindowTitle(tr("StackedWidget"));list = new QListWidget(this);	//新建一个QListWidget控件对象//在新建的QListWidget控件中插入三个条目,作为选择项list->insertItem(0, tr("Window1"));list->insertItem(1, tr("Window2"));list->insertItem(2, tr("Window3"));//创建三个QLabel标签控件对象,作为堆栈窗口需要显示的三层窗体label1 = new QLabel(tr("WindowTest1"));label2 = new QLabel(tr("WindowTest2"));label3 = new QLabel(tr("WindowTest3"));stack = new QStackedWidget(this);//新建一个QStackedWidget堆栈窗体对象//将创建的三个QLabel标签控件依次插入堆栈窗体中stack->addWidget(label1);stack->addWidget(label2);stack->addWidget(label3);QHBoxLayout* mainLayout = new QHBoxLayout(this);//对整个对话框进行布局mainLayout->setMargin(5);		//设定对话框(或窗体)的边距为5mainLayout->setSpacing(5);		//设定各个控件之间的间距为5mainLayout->addWidget(list);mainLayout->addWidget(stack, 0, Qt::AlignHCenter);mainLayout->setStretchFactor(list, 1);mainLayout->setStretchFactor(stack, 3);connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int)));
}

以下两个方法需要我们关注:

  1. mainLayout->setStretchFactor(list, 1):设定可伸缩控件,第一个参数用于指定设置的控件(序号从0开始),第二个参数的值大于0则表示此控件为可伸缩控件。
  2. connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int))):将QListWidget的currentRowChanged信号与堆栈窗体的setCurrentIndex槽函数连接起来,实现按选择显示窗体。此处的堆栈窗体index按插入的顺序从0起依次排序,与QListWidget的条目排序相一致。

基本布局QLayout

Qt提供了QHBoxLayout(水平排列布局)、QVBoxLayout(垂直排列布局)以及QGridLayout(网格排列布局)等布局管理类。各种布局类的派生关系如下:

QLayout
QGridLayout
QBoxLayout
QHBoxLayout
QVBoxLayout

在代码布局中常用的方法有addWidget和addLayout两个方法。

addWidget方法用于加入需要布局的控件,方法原型如下:

void addWidget
(QWidget *widget,	// 需要插入的控件对象int fromRow, 		// 插入的行int fromColumn, 	// 插入的列int rowSpan, 		// 表示占用的行数int columnSpan, 	// 表示占用的列数Qt::Alignment alignment = Qt::Alignment() // 描述各个控件的对齐方式
)

addLayout方法用于加入子布局,方法原型如下:

void addLayout
(QLayout *layout, 	// 需要插入的子布局对象int row, 			// 插入的起始行int column, 		// 插入的起始列int rowSpan, 		// 占用的行数int columnSpan, 	// 占用的列数Qt::Alignment alignment = Qt::Alignment()	// 指定对齐方式
)

下面通过一个UserInfo工程实现一个“用户资料”的功能表单来介绍如何使用基本布局管理,界面效果图如下所示:
在这里插入图片描述
关键代码如下:

UserInfo::UserInfo(QWidget *parent): QDialog(parent)
{setWindowTitle(tr("UserInfo"));/************** 左侧 ******************************/UserNameLabel = new QLabel(QString::fromLocal8Bit("用户名:"));UserNameLineEdit = new QLineEdit;NameLabel = new QLabel(QStringLiteral("姓名:"));NameLineEdit = new QLineEdit;SexLabel = new QLabel(QStringLiteral("性别:"));SexComboBox = new QComboBox;SexComboBox->addItem(QStringLiteral("女"));SexComboBox->addItem(QStringLiteral("男"));DepartmentLabel = new QLabel(QStringLiteral("部门:"));DepartmentTextEdit = new QTextEdit;AgeLabel = new QLabel(QStringLiteral("年龄:"));AgeLineEdit = new QLineEdit;OtherLabel = new QLabel(QStringLiteral("备注:"));OtherLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);LeftLayout = new QGridLayout();//向布局中加入需要布局的控件LeftLayout->addWidget(UserNameLabel, 0, 0);     		 //用户名LeftLayout->addWidget(UserNameLineEdit, 0, 1);LeftLayout->addWidget(NameLabel, 1, 0);                  //姓名LeftLayout->addWidget(NameLineEdit, 1, 1);LeftLayout->addWidget(SexLabel, 2, 0);                  //性别LeftLayout->addWidget(SexComboBox, 2, 1);LeftLayout->addWidget(DepartmentLabel, 3, 0);        	//部门LeftLayout->addWidget(DepartmentTextEdit, 3, 1);LeftLayout->addWidget(AgeLabel, 4, 0);             	    //年龄LeftLayout->addWidget(AgeLineEdit, 4, 1);LeftLayout->addWidget(OtherLabel, 5, 0, 1, 2);       	//其他LeftLayout->setColumnStretch(0, 1);LeftLayout->setColumnStretch(1, 3);/*********右侧*********/HeadLabel = new QLabel(QStringLiteral("头像: "));      //右上角部分HeadIconLabel = new QLabel;QPixmap icon("312.png");HeadIconLabel->setPixmap(icon);HeadIconLabel->resize(icon.width(), icon.height());UpdateHeadBtn = new QPushButton(QStringLiteral("更新"));//完成右上侧头像选择区的布局TopRightLayout = new QHBoxLayout();TopRightLayout->setSpacing(20);		//设定各个控件之间的间距为20TopRightLayout->addWidget(HeadLabel);TopRightLayout->addWidget(HeadIconLabel);TopRightLayout->addWidget(UpdateHeadBtn);IntroductionLabel = new QLabel(QStringLiteral("个人说明:"));		//右下角部分IntroductionTextEdit = new QTextEdit;//完成右侧的布局RightLayout = new QVBoxLayout();RightLayout->setMargin(10);RightLayout->addLayout(TopRightLayout);RightLayout->addWidget(IntroductionLabel);RightLayout->addWidget(IntroductionTextEdit);/*--------------------- 底部 --------------------*/OkBtn = new QPushButton(QStringLiteral("确定"));CancelBtn = new QPushButton(QStringLiteral("取消"));//完成下方两个按钮的布局ButtomLayout = new QHBoxLayout();ButtomLayout->addStretch();	ButtomLayout->addWidget(OkBtn);ButtomLayout->addWidget(CancelBtn);/*---------------------------------------------*/QGridLayout* mainLayout = new QGridLayout(this);mainLayout->setMargin(15);					//设定对话框的边距为15mainLayout->setSpacing(10);mainLayout->addLayout(LeftLayout, 0, 0);mainLayout->addLayout(RightLayout, 0, 1);mainLayout->addLayout(ButtomLayout, 1, 0, 1, 2);mainLayout->setSizeConstraint(QLayout::SetFixedSize);
}

上述代码的一些内容在此解释一下:

  • OtherLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken):设置控件风格。setFrameStyle方法是QFrame类的方法,参数可以通过(|)符号设置多种风格。风格由形状(QFrame::Shape)和阴影(QFrame::Shadow)两项配合设定。其中,形状包括7种,分别是QFrame::NoFrame、QFrame::Box、QFrame::Panel、QFrame::StyledPanel、QFrame::HLine、QFrame::VLine、QFrame::WinPanel;阴影包括3种,分别是QFrame::Plain、QFrame::Raised、QFrame::Sunken。
  • LeftLayout = new QGridLayout():左侧布局,由于此布局管理器不是主布局管理器,所以不用指定父窗口。
  • LeftLayout->setColumnStretch(0, 1)、LeftLayout->setColumnStretch(1, 3):设定两列分别占用空间的比例,本比例为1:3。即时对话框框架大小改变了,两列之间的狂赌比依然保持不变。
  • ButtomLayout->addStretch():在按钮之前插入一个占位符,使两个按钮能够靠右对齐,并且在整个对话框的大小发生改变时,保证按钮的大小不发生变化。
  • QGridLayout* mainLayout = new QGridLayout(this):实现主布局,指定父窗口this,也可调用this->setLayout(mainLayout)实现。
  • mainLayout->setSizeConstraint(QLayout::SetFixedSize):设定最优化显示,并且使用户改变对话框的大小。所谓最优化显示,即控件都按其sizeHint()的大小显示。

工程源码

文章涉及的所有代码都可点击工程源码下载。

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

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

相关文章

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 任务积分优化问题(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 任务积分优化问题(100分) 🌍 评测功能需要 订阅专栏 后私信…

python数据可视化:在带有子图的绘图中添加总标题 matplotlib.pyplot.suptitle()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python数据可视化: 在带有子图的绘 图中 添加总标题 matplotlib.pyplot.suptitle() 请问关于以下代码表述正确的选项是? import matplotlib.pyplot as plt fig, (ax…

LiveMedia视频汇聚平台的设备管理功能

LiveMedia视频汇聚平台的设备管理功能是实现视频资源有效管理和控制的关键组成部分。以下是设备管理功能的详细介绍: 设备接入与管理: 设备添加与编辑:平台支持添加、编辑与删除设备,可编辑的信息包括设备接入的协议类型、服务节…

中小学校共用电脑通过安当SLA产品配置实现开机控制

中小学校公用电脑实现电脑开机控制的必要性主要体现在以下几个方面: 1. 增强安全性: 公用电脑由于使用频繁,容易被未经授权的用户访问,可能存在数据泄露或恶意软件植入的风险。通过实现电脑开机控制,学校可以确保只有…

游戏AI的创造思路-技术基础-深度学习(4)

下面的内容是让AI进行左右互博,这就是传说中的GAN对抗网络 当然,周伯通和GAN真的是难兄难弟,欲练神功,结果被黄药师(欺骗)坑了 目录 3.4. 生成对抗网络(GAN) 3.4.1. 定义 3.4.2.…

ThinkPad 进入BIOS推荐方法ThinkPad(ThinkCentre , ThinkStation)

ThinkPad 进入BIOS推荐方法ThinkPad(ThinkCentre , ThinkStation) 打开系统电源。在启动过程中,按Lenovo , ThinkPad , ThinkStation或ThinkCentre徽标上的F1 。 下图显示了示例BIOS屏幕。 注意&#xff…

PHPMailer发送的中文内容乱码如何解决

一: PHPMailer sdk 文件中有个设置默认编码的位置: vendor/phpmailer/phpmailer/src/PHPMailer.php 二: 实际业务代码中: require /sdk/PHPMailer/vendor/autoload.php;$mail new PHPMailer(true);try {//Server settings$mai…

免费!AI视频一键转绘,​哎哟不错哦~

前段时间给大家介绍过StreamV2V,它基于一种神奇的扩散模型,实现了视频到视频的一键转绘。今天带来StreamV2V视频一键转绘整合包,我只能“说哎哟不错哦”~ StreamV2V简介 你正在看一个视频,突然间,视频中的人物换了张脸…

WebSocket 连接失败的原因及解决方法

WebSocket 目前已经成为了一项极为重要的技术,其允许客户端和服务器之间进行实时、全双工的通信。然而,在实际项目中,开发者时常会遇到 WebSocket 连接失败的情况。这不仅影响了用户体验,还可能导致不可预见的系统错误或数据丢失。…

EE trade:利弗莫尔三步建仓法

在股市投资领域,利弗莫尔这个名字代表着无数的智慧和经历。他的三步建仓法成为了投资者们趋之若鹜的学习对象。本文将详细解析利弗莫尔的著名买入法,通过分步进攻方式,有效掌控市场并实现盈利。 一、利弗莫尔的三步建仓法详解 利弗莫尔三步…

ADS SIPro使用技巧之RapidScan-Z0

PCB走线的阻抗对每个网络的信号完整性至关重要,但是,验证每个信号是不切实际的,尤其对于设计复杂度很高的产品而言,设计者的有限精力只能用于关注关键的设计点,这一过程往往会造成一些设计的疏忽从而导致错误。 ADS SI…

Steam夏促时间 Steam夏促怎么参加外区的促销教程

steam6月28日开启,夏促也是一年中促销力度比较大的促销活动了,想要入手游戏的玩家,这也是一波很好的机会,预告中出现的游戏包括《幻兽帕鲁》《迪士尼梦幻星谷》《庄园领主》《群星》《猛兽派对》《蝙蝠侠:阿卡姆骑士》…

API-事件类型

学习目标&#xff1a; 掌握事件类型 学习内容&#xff1a; 事件类型鼠标事件焦点事件键盘事件文本事件focus选择器案例 事件类型&#xff1a; 鼠标事件&#xff1a; <title>事件类型-鼠标事件</title><style>div {width: 200px;height: 200px;background-c…

【sklearn基础入门教程】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

STM32HAL库--PWR低功耗实验(速记版)

电源控制&#xff08;PWR&#xff09;简介 电源控制部分&#xff08;PWR&#xff09;概述了不同电源域的电源架构以及电源配置控制器。PWR 的内容比较多&#xff0c;我们把它们的主要特性概括为以下 3 点&#xff1a; 电源系统&#xff1a;USB 稳压器、内核域(VCORE)、…

StarRocks 存算分离成本优化最佳实践

序言 StarRocks 存算分离借助对象存储来实现计算和存储能力分离&#xff0c;而存算分离版本 StarRocks 一般来说有以下三方面成本&#xff1a; 计算成本&#xff0c;也即机器使用成本&#xff0c;尤其是运行在公有云上时存储成本&#xff0c;该部分与对象存储上存储的数据量相…

探索SoMeLVLM:面向社交媒体处理的大型视觉语言模型

SoMeLVLM: A Large Vision Language Model for Social Media Processing 论文地址: https://arxiv.org/abs/2402.13022https://arxiv.org/abs/2402.13022发表在ACL 2024 1.概述 在线社交媒体平台涌现出海量的文本与视觉内容,深刻揭示了人们如何交流、互动以及自我表达。随着通…

论文辅导 | 基于贝叶斯优化LSTM的锂电池健康状态评估方法

辅导文章 模型描述 在传统的 LSTM 神经网络中,超参数的取值对模型性能有很大影响,但人工调参很难得到最优解。 因此,本文加入了 BO 来迭代出最优超参数。 在利用LSTM 神经网络评估锂电池 SoH 的基础上,通过 BO来提高评估的精确度。 预测效果

ubuntu卸载python3,重装python2.7

卸载py3 Linux&#xff08;Ubuntu&#xff09;环境下安装卸载Python3&#xff08;避免踩坑&#xff09;_ubuntu卸载python-CSDN博客https://blog.csdn.net/BLee_0123/article/details/136075374 安装py2.7 Ubuntu上重装Python2&#xff08;强烈建议在不删除数据情况下&#…

LLC开关电源开发:如何使用信号发生器与示波器设计环路

如何使用信号发生器与示波器设计环路 一、主回路二、小信号注入三、LLC 数字环路计算书一、主回路 如下图所示为系统整体架构,包括 LLC 主功率线路,采集线路、RC 滤波线路,DSP 运算。DSP 通过采集由差分运放转化而来的输出电压量(一阶 RC 滤除线路杂波),经数字环路产生特…