Python入坑系列-Pyside6桌面编程之Layout设置精美布局效果
bigegpt 2024-10-12 05:25 4 浏览
通过本文章,你可以掌握以下内容:
- Pyside6 Layout介绍
- Pyside6 Layout布局解释及示例
- 自定义Layout,实现部件自动换行
1、Pyside6 Layout介绍
QtWidgets.QLayout是Qt中用于管理窗口或对话框中小部件(控件)布局的基类。它是一个抽象基类,定义了所有布局类共有的接口和行为。QLayout及其子类的主要作用是自动管理小部件的位置和大小,以便于创建整洁和灵活的图形用户界面(GUI),对于复杂界面布局是很重要的,主要作用包括:
- 自动管理小部件位置:QLayout自动计算小部件的位置,使得小部件根据布局规则排列,无需手动指定每个小部件的具体位置。
- 自动调整大小:当窗口大小变化时,QLayout能够自动调整其管理的小部件的大小和位置,确保布局的一致性和响应性。
- 简化界面设计:通过使用布局,开发者可以更加专注于界面的结构设计,而不是具体的位置和大小调整,从而简化了界面设计过程。
- 支持嵌套:布局可以嵌套使用,即一个布局可以包含其他布局,这允许创建复杂的界面结构
2、Pyside6 Layout布局解释及示例
以下是继承自QtWidgets.QLayout的布局,每种布局有对应的行为。
布局 | 行为 | 对应html |
QHBoxLayout | 线性水平布局 | 类似于display: flex; flex-direction: row;的Flexbox布局 |
QVBoxLayout | 线性垂直布局 | 类似于display: flex; flex-direction: column;的Flexbox布局 |
QGridLayout | 在可转位网格 XxY 中 | 类似于html的table行和列 |
QStackedLayout | 堆叠 (z) 于彼此前面 | 类似于css的z-index,并控制隐藏显示效果 |
QHBoxLayout
QHBoxLayout是Qt中的一个布局管理器类,用于按水平方向排列小部件。它继承自QLayout,提供了一种简便的方式来自动管理窗口或对话框中小部件的位置和大小。使用QHBoxLayout,可以将小部件从左到右依次排列,而不需要手动指定每个小部件的具体位置。
简单的示例如下:
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("QHBoxLayout之水平布局")
self.setMinimumSize(400,300)
layout = QHBoxLayout()
layout.addWidget(QPushButton("1"))
layout.addWidget(QPushButton("2"))
layout.addWidget(QPushButton("3"))
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
QVBoxLayout
QVBoxLayout是Qt中的一个布局管理器类,用于垂直方向排列小部件。它继承自QLayout,提供了一种简便的方式来自动管理窗口或对话框中小部件的位置和大小。使用QVBoxLayout,可以将小部件从上到下依次排列,而不需要手动指定每个小部件的具体位置。
简单示例如下:
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("QVBoxLayout之垂直布局")
self.setMinimumSize(400, 300)
layout = QVBoxLayout()
layout.addWidget(QPushButton("1"))
layout.addWidget(QPushButton("2"))
layout.addWidget(QPushButton("3"))
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
效果图如下:
QGridLayout
QGridLayout是Qt中一个非常强大的布局管理器,它提供一种网格式布局,这种布局由行和列组成(类似table),每个小部件占据网格中的一个或多个单元格。QGridLayout提供了灵活的方式来创建复杂的用户界面,使得小部件的布局可以精确控制,同时也能自动适应窗口大小的变化,主要特性有:
- 行列管理:可以指定小部件应该放在网格的哪一行哪一列,甚至可以跨越多行多列。
- 自动调整大小:当窗口大小改变时,QGridLayout会自动调整小部件的大小和位置,保持布局的整洁和一致性。
- 最小宽度和拉伸因子:每列(或行)可以有一个最小宽度和一个拉伸因子,这决定了在可用空间中它们将如何分配额外的空间。
- 间距和边距:可以设置小部件之间的间距(spacing())和布局边缘的边距(内容边距),以控制布局的外观。
示例代码如下:
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("QGridLayout之网格布局")
self.setMinimumSize(400, 300)
layout = QGridLayout()
# 为窗口部件设置样式表,添加边框
self.setStyleSheet("QWidget { border: 2px solid black; }")
layout.addWidget(QLabel('第0行第0列'), 0, 0)
layout.addWidget(QLabel('第0行第1列'), 0, 1)
layout.addWidget(QLabel('第1行第0列'), 1, 0)
layout.addWidget(QLabel('第1行第1列'), 1, 1)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
效果图如下:
QStackedLayout
QStackedLayout是Qt中的一个布局管理器,它可以在相同的空间内堆叠多个小部件,但一次只显示一个小部件。这种布局非常适合用于实现向导、选项卡和其他需要在多个页面之间切换的界面。
主要特性:
- 堆叠小部件:在同一个布局空间内堆叠多个小部件。
- 单一可见性:一次只有一个小部件可见。
- 动态切换:可以编程方式动态切换当前可见的小部件
常用方法技巧:indexOf()函数返回小部件在该列表中的索引。可以使用addWidget()函数添加小部件到列表末尾,或者使用insertWidget()函数在给定索引处插入。removeWidget()函数从布局中移除给定索引的小部件。可以使用count()函数获取布局中包含的小部件数量。widget()函数返回给定索引位置的小部件。当前显示在屏幕上的小部件的索引由currentIndex()给出,并且可以使用setCurrentIndex()进行更改。以类似的方式,可以使用currentWidget()函数检索当前显示的小部件,并使用setCurrentWidget()函数进行更改。每当布局中的当前小部件发生变化或从布局中移除小部件时,分别会发出currentChanged()和widgetRemoved()信号。
示例代码如下:
import sys
from PySide6.QtGui import QPalette, QColor
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QStackedLayout之堆叠布局")
self.setMinimumSize(400, 300)
pagelayout = QVBoxLayout()
button_layout = QHBoxLayout()
self.stacklayout = QStackedLayout()
pagelayout.addLayout(button_layout)
pagelayout.addLayout(self.stacklayout)
btn = QPushButton("red")
btn.pressed.connect(self.activate_tab_1)
button_layout.addWidget(btn)
self.stacklayout.addWidget(Color("red"))
btn = QPushButton("green")
btn.pressed.connect(self.activate_tab_2)
button_layout.addWidget(btn)
self.stacklayout.addWidget(Color("green"))
btn = QPushButton("yellow")
btn.pressed.connect(self.activate_tab_3)
button_layout.addWidget(btn)
self.stacklayout.addWidget(Color("yellow"))
widget = QWidget()
widget.setLayout(pagelayout)
self.setCentralWidget(widget)
def activate_tab_1(self):
self.stacklayout.setCurrentIndex(0)
def activate_tab_2(self):
self.stacklayout.setCurrentIndex(1)
def activate_tab_3(self):
self.stacklayout.setCurrentIndex(2)
class Color(QWidget):
def __init__(self, color):
super(Color, self).__init__()
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
效果图如下:
混合布局
使用QHBoxLayout、QVBoxLayout、QGridLayout、QStackedLayout这几种布局组合使用,来控制界面的整体风格视角,制作精美的布局效果
示例代码如下:
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("混合布局")
self.setMinimumSize(400, 300)
self.setStyleSheet("QLabel { border: 1px solid blue; }")
layout1 = QHBoxLayout()
layout2 = QVBoxLayout()
layout3 = QVBoxLayout()
layout1.setContentsMargins(0,0,0,0)
layout1.setSpacing(20)
layout2.addWidget(QLabel('hbox1-QVBoxLayout1'))
layout2.addWidget(QLabel('hbox1-QVBoxLayout2'))
layout2.addWidget(QLabel('hbox1-QVBoxLayout3'))
layout1.addLayout(layout2)
layout1.addWidget(QLabel('hbox2'))
layout3.addWidget(QLabel('hbox2-QVBoxLayout1'))
layout3.addWidget(QLabel('hbox2-QVBoxLayout2'))
layout1.addLayout(layout3)
widget = QWidget()
widget.setLayout(layout1)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
效果图如下:
注意:QLayout边框及样式不能通过这种方式来设置样式效果,需要指定Widget的样式
#无效果
self.setStyleSheet("QHBoxLayout { border: 1px solid black; }")
#有效果
self.setStyleSheet("QLabel { border: 1px solid blue; }")
自定义Layout,实现部件自动换行
由于QHBoxLayout、QVBoxLayout、QGridLayout、QStackedLayout布局放置的控件,不增加任何处理,生成的控件会固定住窗口大小,可以通过下面来动态排列控件。
示例代码如下:
import sys
from PySide6.QtCore import QRect, QSize, QPoint, Qt
from PySide6.QtWidgets import *
class FlowLayout(QLayout):
def __init__(self, parent=None, margin=0, spacing=-1):
super(FlowLayout, self).__init__(parent)
if parent is not None:
self.setContentsMargins(margin, margin, margin, margin)
self.setSpacing(spacing)
self.items = []
def addItem(self, item):
self.items.append(item)
def count(self):
return len(self.items)
def itemAt(self, index):
if index >= 0 and index < len(self.items):
return self.items[index]
return None
def takeAt(self, index):
if index >= 0 and index < len(self.items):
return self.items.pop(index)
return None
def expandingDirections(self):
return 0
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
height = self.doLayout(QRect(0, 0, width, 0), True)
return height
def setGeometry(self, rect):
super(FlowLayout, self).setGeometry(rect)
self.doLayout(rect, False)
def sizeHint(self):
return QSize(self.doLayout(QRect(0, 0, 10000, 0), True), 10000)
def doLayout(self, rect, testOnly):
x = rect.x()
y = rect.y()
lineHeight = 0
for item in self.items:
wid = item.widget()
spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,Qt.Horizontal)
spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,Qt.Vertical)
nextX = x + item.sizeHint().width() + spaceX
if nextX - spaceX > rect.right() and lineHeight > 0:
x = rect.x()
y = y + lineHeight + spaceY
nextX = x + item.sizeHint().width() + spaceX
lineHeight = 0
if not testOnly:
item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))
x = nextX
lineHeight = max(lineHeight, item.sizeHint().height())
return y + lineHeight - rect.y()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWidget = QWidget()
mainWidget.setMinimumSize(300, 200)
layout = FlowLayout(mainWidget)
for i in range(50):
layout.addWidget(QPushButton(f'Button {i}'))
mainWidget.setLayout(layout)
mainWidget.show()
sys.exit(app.exec_())
效果如下:
相关推荐
- 得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践
-
一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...
- warm-flow新春版:网关直连和流程图重构
-
本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...
- 扣子空间体验报告
-
在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...
- spider-flow:开源的可视化方式定义爬虫方案
-
spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...
- solon-flow 你好世界!
-
solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...
- 新一代开源爬虫平台:SpiderFlow
-
SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...
- 通过 SQL 训练机器学习模型的引擎
-
关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...
- 鼠须管输入法rime for Mac
-
鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...
- Go语言 1.20 版本正式发布:新版详细介绍
-
Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...
- iOS 10平台SpriteKit新特性之Tile Maps(上)
-
简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...
- 程序员简历例句—范例Java、Python、C++模板
-
个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...
- Telerik UI for iOS Q3 2015正式发布
-
近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...
- ios使用ijkplayer+nginx进行视频直播
-
上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...
- IOS技术分享|iOS快速生成开发文档(一)
-
前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...
- macOS下配置VS Code C++开发环境
-
本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- httperror403.14-forbidden (63)
- logstashinput (65)
- hadoop端口 (65)
- dockernetworkconnect (63)
- esxi7 (63)
- vue阻止冒泡 (67)
- c#for循环 (63)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- java大写转小写 (63)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)