Qt/PySide6 设计师:designer

From ---> Qt Designer 使用全攻略:https://blog.l0v0.com/posts/bea01990.html
Qt设计师手册:https://doc.qt.io/qt-6/qtdesigner-manual.html

1、Designer 简介 

什么是 Qt Designer

QtDesigner 是 QT 官方推出的图形化制作GUI界面的工具。通过拖拽控件的方式就可以快速的制作出一个 GUI 界面。可视化搭建好图形界面之后,只需要关注业务代码即可。Qt Designer 的设计符合MVC的架构,其实现了视图和逻辑的分离。使用 Qt designer 就是为了快速创建出 UI 界面,毕竟手动实现界面效率还是比较低的,特别是还要考虑各种固定组件的布局位置。组件触发可以放在 python 代码中完成。官网说明:https://doc.qt.io/qt-6/designer-to-know.html

Qt Designer 的使用方法其实不难,从左侧的组件库里面拖拽组件放到窗口里面。然后可以像控制窗口一样可以用左键拖拽、缩放组件。最基础的使用就是这些,懂了这些操作完全就可以自己拖拽组件搭配出想要的界面。

Android 界面的可视化设计。Android Studio 自带可视化设计。

Web 前端 Bootstrap 可视化布局系统:https://www.bootcss.com/p/layoutit/

安装 Qt Designer

安装 Qt Designer 的方法有好几种:

  • 安装官方提供的 Qt Creator 开发软件。Qt Creator 是一个 IDE,是针对 Qt 优化的 C++ 开发平台,里面内置了许多 Qt 开发相关的工具,Qt Designer 就在其中。
  • 安装任意 Qt Python 包
  • 安装 Maya 自带 Qt Designer

这里以安装官方的Python包PySide6为例,使用豆瓣源安装:pip install -i http://pypi.doubanio.com/simple/ PySide6 --trusted-host pypi.doubanio.com,安装后就可以在Python的site-packages\PySide6目录中找到designer.exe,可以创建个快捷方式放在桌面上。

第3方 控件库

Designer 本身自带的控件比较少,控件样式显示效果也一般,可以安装第3方控件库来增加控件数量,和美化 GUI 界面显示。告别原始 UI 样式。

Fluent Design 控件库 :https://github.com/zhiyiYo/PyQt-Fluent-Widgets

在线文档

Fluent Design 是一个强大、可扩展、美观优雅的组件库,包含了大量类似 InfoBar、Flyout、CommandBar 以及 Pivot 等组件类,可以组合使用并直接在 设计师 上实现任何 UI 设计。拖拖拽拽,无需书写 QSS,即可快速构建美观的界面

  • PySide2、PySide6、PyQt6 控件库: PySide2PySide6PyQt6 。
  • 注意: 不要同时安装 PyQt-Fluent-Widgets、PyQt6-Fluent-Widgets、PySide2-Fluent-Widgets、PySide6-Fluent-Widgets,因为包名都是 qfluentwidgets.

运行 Fluent 示例

安装完 pyqt-fluent-widgets 包后,下载仓库源代码,切换到 examples 目录下运行示例代码。
        cd examples/gallery
        python demo.py

启动 Fluent Design

运行 python ./tools/designer.py 来启动安装了 PyQt-Fluent-Widgets 插件的 QtDesigner。如果操作成功,QtDesigner 的侧边栏中将会显示 PyQt-Fluent-Widgets 的组件。

建议使用虚拟环境。

conda create -n qt5

conda activate qt5

pip install PyQt5
pip install pyqt5-tools

部分控件效果展示

拥抱 Fluent Design 风格 PyQt/PySide 组件库:https://blog.csdn.net/zhiyiYo/article/details/131328168

启动 Qt Designer

启动后主窗口如下,弹出一个窗口选择Form模板,其中 Widget 与 Main Window 最常用

这里选择 Main Window 点击创建。然后就可以拖拽左侧的组件到窗口上。按住 ctrl 拖拽可以快速复制组件。Ctrl+R (菜单栏 ---> 窗体 ---> 预览) 可以预览设计好的界面。

工具栏上的布局按钮可以改变窗口的布局,也可以从左侧拖拽相关的布局到窗口上。通过这些布局就可以让组件等分排布,从而减少 UI 的凌乱,让界面看起来更加美观

  • QHBoxLayout - 横向布局。 就是将布局内部的组件 水平方向 等分排列
  • QVBoxLayout - 竖向布局。就是将布局内部的组件 垂直方向 等分排列
  • QGridLayout - 网格布局。就是将布局内部分成好多网格,类似 Excel 表格。可以让组件占用多个网格,或者空出多余的网格。

对象 查看器

可以查看主窗口中已放置的对象(就是已经拖拽的控件)以及其相应地Qt类。可以快速查看有哪些哪些控件,以及控件所属层级。

将 QWidget 修改为特定组件

Qt Designer 无法创建一个纯按钮之类的 ui 文件。默认的 ui 文件必须是个容器。但是有个需求就是要弄一个纯 按钮 的 ui 文件,应该要怎么实现。可以通过修改 xml 类来实现。首先默认创建一个 QWidget 的 ui 文件。然后将 ui 文件的 QWidget 修改为 QPushButton,重新用 QtDesigner 打开这个文件。会发现 Qt Designer 里面呈现的是一个按钮而不是 QWidget 。

给 QWidget 添加 MenuBar

也可以实现给 QWidget 添加 QMenuBar 的骚操作。默认情况下,只有 QMainWindow 可以在 Qt Designer 里面配置 QMenuBar 实现下来菜单。由于左侧的组件列表没有 QMenuBar 组件,所以根本就无法添加到 QWidget 里面。通过编辑 ui 文件,然后用上面的方法将两个 ui 文件拼接到一起,就可以实现这种骚操作。这样就不需要手动写 QMenuBar 代码了。

组件提升

默认情况下, Qt Designer 只能拖拽一些基础组件,如果想要用自定义的组件,似乎就无法实现了。其实不然,通过 promote 提升,可以实现将组件提升为 第三方 类。当然,组件提升无法在 Qt Designer 直接预览到效果,只能看到基类的 UI。如果要想实现在 Qt Designer 直接看到效果,也可以用 C++ 开发 Qt Designer 的插件,直接扩展出自定义组件。基础的提升操作如下

看起来似乎也是针对 C++ 才有效。其实不然。

先添加一个配置头文件的配置,然后再点击 Promote 来提升组件。下面编译这个 ui 文件可以看到神奇的 promote 效果

from PySide2 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.pushButton = MPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(60, 60, 75, 23))
        self.pushButton.setObjectName("pushButton")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1))
        self.pushButton.setText(QtWidgets.QApplication.translate("Form", "PushButton", None, -1))

from dayu_widgets.push_button import MPushButton

头文件自动转为 Python 的库, 类名就对应库里面的类。只要自定义的组件类按照默认的 构造函数传参, 就不存在什么问题。这个东西其实也可以直接用 ui 文件加载的方式调用起来,这里用到了 QUiLoader registerCustomWidget 的使用方法。通过这个方法可以将自定义的组件注册到 QUiLoader 里面,然后 QUiLoader 读取 ui 文件的时候自动映射到第三方组件上。示例:dayu_widget。这个 dayu_widget 第三方库通过 Qt Designer 直接嵌入的。PyToolkit文章

属性 编辑器

右侧的 "属性编辑器" 可以编辑UI控件的属性,不过很多时候都是用代码来动态修改这些属性。objectName 比较重要,因为在代码中是通过 objectName 这个属性来调用控件的。

具体的组件属性可以参照 Qt 的文档,或者使用 "属性编辑器" 搜索查找对应的属性。

主要包含属性有如下:

objectName        控件对象名称
geometry            相应宽和高与坐标
sizePolicy          控件大小的策略
minimumSize    最小的宽和高
maximumSize    最大的宽和高
font         字体
cursor    光标

自定义 property。属性编辑器可以配置自定义属性到组件里面。比较常用的就是 字符串 和 布尔类型。点击其他还能看到更多 C++ 相关的类型,一般情况下也用不上。

挂载配置文件。基于字符串可以挂载的原理,可以弄一套 json 配置到组件里面。然后再 Python 固定读取这个属性解析 json 配置,就甚至可以实现在 Qt Designer 配置组件的基础行为。组件功能可以更为灵活,不过也不建议配置过于复杂,建议业务逻辑还是写到代码里合适。

后续 Python 读取这个属性如下

{
    "method" : {
        "setText":"输出名称"
    }
}

import os
import json
from collections import OrderedDict

from Qt import QtWidgets,QtGui,QtCore
from Qt.QtCompat import loadUi

def ui_PyInit(widget):
    """
    递归遍历所有的 Widget 组件
    """
    if not hasattr(widget,"children"):
        return

    # NOTE 初始化 PyInit 中配置的方法
    data = widget.property("PyInit")
    if data:
        try:
            data = json.loads(data,object_pairs_hook=OrderedDict)
            for method,param in data['method'].items():
                param = param if isinstance(param,list) else [param]
                getattr(widget,method)(*param)
        except:
            pass

    for child in widget.children():
        ui_PyInit(child)

class TestWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        DIR  = os.path.dirname(__file__)
        ui_path = os.path.join(DIR,"test.ui")
        # NOTE 加载 ui 文件
        loadUi(ui_path,self)
        # NOTE 初始化配置方法
        ui_PyInit(self)

设置 stylesheet

Qt 同样提供了类似于 Web 的样式表用来快速定义组件的显示效果。可以在属性编辑器的 StyleSheet 里面进行自定义。QSS (称为 Qt Style Sheets )  背后其实 Qt 的 Paint 事件,通过样式表来简化手动绘制的操作。如果想要实现一些自定义的图形绘制, 需要代码通过 Qt 的 PaintEvent 实现。

关于样式表配置可以参照网上文章以及官网

信号槽 连接

Qt Designer 可以设置组件的信号槽连接。

Qt 的信号槽可以实现一些 Qt 组件的事件回调,比如点击按钮的触发,数据变动触发等等。通常过去都是用代码连接信号槽。:https://blog.l0v0.com/posts/6830570a.html

资源 浏览器(Resource Browser)

资源浏览器中可以添加相应地如图片素材,作为 Label 或 Button 等控件的背景图片等。

布局(Layout) 管理

Qt Designer 布局:https://blog.csdn.net/qq_22238533/article/details/78952706
使用 Qt Designer 设计界面:https://blog.csdn.net/a10929/article/details/78114261
养薛定谔的猫 简书:https://www.jianshu.com/u/bf82b363ae88

使用代码布局时,默认是所有控件撑满整个布局文件。如果是使用拖拽方式布局时,控件大小就是拖拽时的大小。但是拖拽方式遇到窗口界面缩放时,组件不会自动适应窗口的变化,就需要 Layout 去配合。Qt 提供的布局有:

继承图:

在代码中,在布局中添加控件用 addWidght(),添加布局用 addLayout()

  • 垂直布局 (VBoxLayout ),布局内的控件按照从上到下的顺序纵向排列

  • 水平布局 (HBoxLayout )。布局内的控件按照从左到右的顺序横向排列
  • 栅格(Grid)布局,也叫网格布局。就是划分成若干行与若干列,然后将控件放入网格中,控件可以只占一个网格,也可以跨越占用多个网格。

  • 表单(Form)布局。控件以两列的形式布局在窗口中,左边为标签,右边为输入控件。

布局的对齐方式:

QtCore.Qt.AlignLeft        水平方向居左对齐
QtCore.Qt.AlignRight    水平方向居右对齐
QtCore.Qt.AlignCenter    水平方向居中对齐
QtCore.Qt.AlignJustify    水平方向两端对齐
QtCore.Qt.AlignTop        垂直方向靠上对齐
QtCore.Qt.AlignBottom    垂直方向靠下对齐
QtCore.Qt.AlignVCenter    垂直方向居中对齐

"盒布局" 名字虽然听起来怪怪的,但是却非常形象,主要借助两个函数QHBoxLayout(水平方向)和 QVBoxLayout(竖直方向),建立一个个水平方向或者是竖直方向的 "盒子",盒子本身整齐排列,同时把盒子内部的组件也整齐排列,这样整体来看就显得会很整齐。

一个盒布局实例

在盒布局里,还有一个非常有用的函数:布局.addStretch(int)。这个函数很形象,就是在布局之内添加一个弹簧,使组件之间有空隙。int 值代表 "弹簧" 的长度。

这里写图片描述

弹簧控件是按照这个弹簧的比例分的,在页面布局中使用广泛

hbox.addStretch(1)  # hbox 是一个水平 "盒子"
hbox.addWidget(Button1)
hbox.addStretch(1)
hbox.addWidget(Button2)
hbox.addStretch(1)

就是把 hbox 这个盒子剩余空间等分成三份,如果把中间的弹簧改成2,那么就是把这个盒子剩余空间等分成4分,中间的空间占两份。对比如下:

这里写图片描述

按比例布局

# 调用 setStretchFactor 函数后,三个控件的比例分别为:1:2:2

layout.addWidget(btn)
layout.addWidget(tableWidget)
layout.addLayout(h_layout)

layout.setStretchFactor(btn, 1)
layout.setStretchFactor(tableWidget, 2)
layout.setStretchFactor(h_layout, 2)

水平居左对齐 ~ QtCore.Qt.AlignLeft

def initUI(self):
    layout = QHBoxLayout()
    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))

    layout.addStretch(1) # 新增这一行。把 剩余空间分成一份,最后添加这一份的间隔
    ......

# 在两个控件后增加这一行,相当于水平布局中存在:按钮1按钮2stretch。此时 addStretch 的参数只要大于0,则表示占满整个布局最后一部分,前面的控件显示为正常大小,不要拉伸。

水平居右对齐 ~ QtCore.Qt.AlignRight

def initUI(self):
    layout = QHBoxLayout()

    layout.addStretch(1) # 新增这一行在控件前面

    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))
    ......

# 这一行加入到布局中所有控件之前,相当于水平布局中存在:stretch-按钮1-按钮2,表示占满整个布局的最开始部分,后面的控件显示为正常大小,不要拉伸。

水平居中对齐 ~ QtCore.Qt.AlignCenter

def initUI(self):
    layout = QHBoxLayout()

    layout.addStretch(1) # 前面增加一行

    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))

    layout.addStretch(1) #后面增加一行
    ......

stretch按钮1按钮2stretch,表示左右两边充满,控件占据中间位置

注意:当一个布局中出现多个addStretch时,后面的参数就有意义了,其表示整个布局的大小减去控件总大小进行n等份分配。

def initUI(self):
    layout = QHBoxLayout()
    layout.addStretch(1)  # 注意1
    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))
    layout.addStretch(3)  # 注意2

# 表示除去控件1、控件2 的宽度,剩余部分四等份,前面占据一份,最后面占据三份

水平两端对齐 ~ QtCore.Qt.AlignJustify

def initUI(self):
    layout = QHBoxLayout()
    layout.addWidget(QPushButton(str(1))
    layout.addStretch(1)  # 添加行
    layout.addWidget(QPushButton(str(2))

垂直顶部对齐 ~ QtCore.Qt.AlignTop

def initUI(self):
    layout = QVBoxLayout()
    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))
    layout.addStretch(1)  # 添加行

垂直底部对齐 ~ QtCore.Qt.AlignBottom

def initUI(self):
    layout = QVBoxLayout()
    layout.addStretch(1)  # 添加行
    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))

垂直居中对齐 ~ QtCore.Qt.AlignVCenter

def initUI(self):
    layout = QVBoxLayout()
    layout.addStretch(1)  # 添加行
    layout.addWidget(QPushButton(str(1))
    layout.addWidget(QPushButton(str(2))
    layout.addStretch(1)  # 添加行

垂直两端对齐

def initUI(self):
    layout = QVBoxLayout()
    layout.addWidget(QPushButton(str(1))
    layout.addStretch(1)  # 添加行
    layout.addWidget(QPushButton(str(2))

组合布局。示例:左上角、右下角等

def initUI(self):
    layout1 = QHBoxLayout()
    layout1.addWidget(QPushButton(str(1))
    layout1.addWidget(QPushButton(str(2))
    layout1.addStretch(1) # 水平居左

    layout2 = QVBoxLayout()
    layout2.addLayout(layout1)
    layout2.addStretch(1) # 垂直顶部对齐
    
    self.setLayout(layout2)
    ......

间距 (addSpacing)。就是设置控件之间的间距

addSpacing(self, int)              # 设置各控件的上下间距,通过该方法可以增加额外的控件
addStretch(self, int)              # 分配布局大小比例
insertStretch(index, stretch = 0)  # 在指定控件间隔处添加布局比例
insertSpacing(index, size)         #在指定控件间隔处设置间隔大小

def initUI(self):
    layout = QHBoxLayout()
    layout.addWidget(QPushButton(str(1))
    layout.addSpacing(100)
    layout.addWidget(QPushButton(str(2))

间距设置可以放置在任何地方,对于调整控件位置十分有效。相当于在控件之间添加了一个空的控件。详细的用法与addStrech类似,参考以上使用即可。

QSplitter (分割),控件大小占比不固定,可以通过拖拽两个控件的边界改变控件占比大小

import sys
from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QFrame,
                             QSplitter, QTextEdit, QApplication)
from PyQt5.QtCore import Qt


class SplitterExample(QWidget):
    def __init__(self):
        super(SplitterExample, self).__init__()
        self.initUI()

    def initUI(self):
        # 初始化控件
        topleft = QFrame()
        topleft.setFrameShape(QFrame.StyledPanel)
        bottom = QFrame()
        bottom.setFrameShape(QFrame.StyledPanel)
        textedit = QTextEdit()

        # 设置第一个Splitter的布局方向
        splitter1 = QSplitter(Qt.Horizontal)
        # 为第一个Splitter添加控件,并设置两个控件所占空间大小
        splitter1.addWidget(topleft)
        splitter1.addWidget(textedit)
        splitter1.setSizes([100, 200])

        # 设置第二个Splitter的布局方向,将第一个Splitter嵌套在第二个里
        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)

        # 设置全局布局
        hbox = QHBoxLayout(self)
        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setWindowTitle('QSplitter 例子')
        self.setGeometry(300, 300, 300, 200)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = SplitterExample()
    demo.show()
    sys.exit(app.exec_())

可以通过工具栏将切换布局。

布局还可以嵌套,就是布局里面添加布局,可以实现复杂的页面设计

嵌套布局示例

在 Qt Designer 中实现布局有两种方式,

  • 通过 布局管理器 进行布局
  • 通过 容器控件 进行布局。

通过 布局管理器 进行布局。在左侧的工具箱中随意拖动一些控件,例如:按钮、标签、输入框等控件 到 主窗口中。

由于刚才是随意拖拽至主窗口,因此所有控件的排放是乱七八糟的。此时,我们不选中任何控件,在空白处点击右键,找到弹出菜单最下方的 Layout 布局。

可以看到,在右键菜单中可以指定布局的方式以及相应布局方式的快捷键。这里我们选择 Lay Out Vertically(垂直布局),整个主窗口内的所有控件一瞬间都垂直着排列整齐了。

此时如果需要调整垂直布局的顺序,只需按住待调整的控件,上下拖动即可。但是这样布局是针对整个窗口的,有时我们需要让不同的布局有父子关系的继承。那么这时就不能单纯地在空白的地方点击右键来布局了。

再次 "点击右键 -> 布局 -> 拆分布局",  然后选中需要水平布局的2个控件,选中后点击右键,水平布局。再选中另外两个控件,选择水平布局。此时的主窗口应该如图所示:

最后,我们再将两个布局选中,点击右键垂直布局,来排列两个水平布局。

最后在空白区域再次使用垂直布局。这样即使我们缩放窗口,整个窗口内的控件也会跟着窗口的变化做出相应改变了。

在上述操作的过程中,我们的一系列操作有决定这些物体的父子关系(层级关系)。而其层级关系在对象查看器中可以直观地看出。

布局管理 生成 代码,把布局保存为.ui文件,并使用 PyUIC 转换为 .py 文件。

使用 容器 进行布局。

容器(Container)指的就是能容纳其他子控件的一个控件。使用容器控件可以将容器控件中的所有控件归为一类,从而区别于其他的控件。当然,正如上文提到过的,使用容器也可以对控件进行布局。

首先,从左侧的 Container 中拖出一个 Frame 控件到主窗口中,再拖出一些其他控件到 Frame 中。如下图:

选中 Frame 中空白地方,点击右键 -> 布局 -> 水平布局,则会自动水平排列 Frame 中的控件。

当我们需要变更 Frame 的位置的时候,可以直接拖动 Frame 到相应地位置,这样管理更加方便。使用容器进行布局的实质也是使用容器管理器进行布局的。

绝对布局。最简单的布局则是输入控件的 Geometry 属性值。

在属性编辑器中,可以修改 X、Y 值来将控件放置在相应的位置,修改 Width 和 Height 来更改控件高度。

名称含义
X290控件的最左上角距离主窗口的左侧290px
Y140控件的最左上角距离主窗口的上方140px
Width93按钮的宽度为93px
Height28按钮的高度为23px

而上述的 Geometry 属性在 .py 代码中如下:

self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 140, 93, 28))
self.pushButton.setObjectName("pushButton")

可以看到,上述代码的第二行通过 setGeometry 方法指定了 Geometry 属性的四个值。通过以上的方法,我们可以对任何一个控件进行布局。

示例:计算器界面

使用网格布局(Grid Layout)

首先分析整数计算器需要的一些按钮:
数字键:0-9共10个。
操作符:+ - * / = CE共6个
在 Designer 的主窗口中创建 16 个按钮之后,按照4行4列的顺序进行摆放。

并且修改按钮的属性中的 objectName 为相对于的名称。如数字 0 的 objectName 设置为 Num_0,操作符 + 的 objectName 设置为 OP_plus。对于按钮的显示名称的修改,在主窗口中双击相应按钮则可以快速修改。由于计算器中的按钮是正方形(通常选择正方形),而且不想让这些按钮根据窗口的大小进行变化,通过全选16个按钮(在主窗口中使用鼠标左键拖出选择框,选中16个按钮)在右侧找到 mininumSize 和 maximumSize 属性。点击其左面的箭头符号展开选项,将其宽和高固定为 60。这样就不会因为缩放窗口而造成按钮的大小变化了。

在对所有按钮完成相应操作之后,我们选中16个按钮,点击右键,使用网格布局来实现布局。

使用 Spacer 增加空白间隔

在 输入控件 面板中,拖一个 line Edit 控件到计算器窗口上,用来显示输入结果与计算结果。

通过在空白地方右键,对主窗口使用Vertical Lay Out。

此时,我们实现了一个计算器的布局。但显示框与下面的按钮距离太近。这时便需要使用左侧工具箱内的 Spacer 控件。

Spacer 顾名思义 "分隔器" 。可以通过以占位的形式来将布局中的不同控件分开部分举例。
此时,我们拖动一个 Vertical Spacer 到 Line Edit 与下面的键盘之间。同样,Horizontal Spacer也可以用来水平地分离控件之间的距离。

虽然 Spacer 在我们的 Qt Designer 编辑器中是以蓝色的类似弹簧的外观存在的,但是在真正的窗体中,Spacer 是隐形的。

但这时的 Spacer 大小和 Line Edit 的大小都不是想要的,而且也无法通过鼠标来拖动。如果想要改变这些,则需要进一步了解这些控件的一些属性。

sizePolicy 尺寸策略

在 Designer 中,控件的尺寸是可以变化的。每个控件都拥有 sizeHint 和 minisizeHint 两个尺寸。sizeHint 即尺寸提示;minisizeHint 则是最小尺寸。尺寸提示也是控件的期望尺寸,最小尺寸即窗口可以被压缩到的最小的尺寸。sizePolicy 与 sizeHint 和 minisizeHint 息息相关。

对于布局管理器中的布局无法满足的要求的时候,sizePolicy 属性便派上了用场。

sizePolicy 可以实现控件的微调。sizePolicy 中共有如下几种水平和垂直策略。

参数说明:

在 sizePolicy 的 Horizontal Policy 和 Vertical Policy 下面还有 Horizontal Stretch 和 Vertical Stretch 两个属性。现在找到 Spacer,并修改其属性的 Height 为 10。

并将其 sizeType 修改为 Fixed 固定。此时,观察左面的计算器的主界面显示栏 Line Edit 与下面的键盘之间的间距变小了。

保存 ui 文件并转 py

官方的 XML scheme 文档:https://doc.qt.io/qt-6/designer-ui-file-format.html

设计好 UI 后 ctrl+s 保存当前编辑的文件,Qt Designer 会输出一个后缀为 ui 的文件。用文本编辑器打开 ui 文件,会发现 ui 文件实质上是一个 xml 文件,这个文件可以转为 .h 文件 .py 文件。这里将.ui文件转换到.py文件。安装完 PySide6 后,会有一个 pyside6-uic.exe 文件,这个工具可以把 ui 文件转成 Python 代码文件,在代码中引入这个py文件,一个 GUI 程序就设计好了。

用法::pyside6-uic.exe ui文件 -o 输出的python文件
用法::pyside6-uic.exe ui文件 > 输出的python文件

也可以不用编译,直接在 Python 代码中加载 ui 文件

官网说明:https://doc.qt.io/qtforpython-6/tutorials/basictutorial/uifiles.html

import sys
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import QFile, QIODevice

if __name__ == "__main__":
    app = QApplication(sys.argv)

    ui_file_name = "ui_demo.ui"
    ui_file = QFile(ui_file_name)
    if not ui_file.open(QIODevice.ReadOnly):
        print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
        sys.exit(-1)
    loader = QUiLoader()
    window = loader.load(ui_file)
    ui_file.close()
    if not window:
        print(loader.errorString())
        sys.exit(-1)
    window.show()

    sys.exit(app.exec())

如果通过调试程序来布局GUI界面,将是极其痛苦的。而通过Qt Designer 就可以快速地制作UI,并生成Python的代码,从而实现快速地UI的开发。

VScode 对接 Qt Designer

VScode 有一个非常好用的插件,可以自己配置 Qt 工具的路径

配置好这些,打开 ui 文件可以直接通过 VScode 打开设置好的 Qt Designer,也可以自动 compile 出代码

Qt Designer 功能小技巧

qrc 资源

设置资源路径,可以加载外部的图片资源。

在这个过程会通过 Qt Designer 创建了一个 qrc 文件。这个 qrc 文件也是一个 xml ,用来描述索引的图片资源的位置。要使用 Qt 的 qrc 资源文件需要将资源编译为 Python 代码。这个过程会自动将图片资源转换为 Python 的字符信息。

编译 qrc 文件需要用 pyside6-rcc.exe 执行程序进行转换。

pyside6-rcc.exe --help

Options:
  -?, -h, --help                        Displays help on commandline options.
  --help-all                            Displays help, including generic Qt
                                        options.
  -v, --version                         Displays version information.
  -o, --output <file>                   Write output to <file> rather than
                                        stdout.
  -t, --temp <file>                     Use temporary <file> for big resources.
  --name <name>                         Create an external initialization
                                        function with <name>.
  --root <path>                         Prefix resource access path with root
                                        path.
  --compress-algo <algo>                Compress input files using algorithm
                                        <algo> ([zlib], none).
  --compress <level>                    Compress input files by <level>.
  --no-compress                         Disable all compression. Same as
                                        --compress-algo=none.
  --no-zstd                             Disable usage of zstd compression.
  --threshold <level>                   Threshold to consider compressing
                                        files.
  --binary                              Output a binary file for use as a
                                        dynamic resource.
  -g, --generator <cpp|python|python2>  Select generator.
  --pass <number>                       Pass number for big resources
  --namespace                           Turn off namespace macros.
  --verbose                             Enable verbose mode.
  --list                                Only list .qrc file entries, do not
                                        generate code.
  --list-mapping                        Only output a mapping of resource paths
                                        to file system paths defined in the .qrc
                                        file, do not generate code.
  -d, --depfile <file>                  Write a depfile with the .qrc
                                        dependencies to <file>.
  --project                             Output a resource file containing all
                                        files from the current directory.
  --format-version <number>             The RCC format version to write

Arguments:
  inputs                                Input files (*.qrc).

示例:pyside6-rcc test.qrc -o test_qrc.py 

执行命令即可将 qrc 文件转换为 python 代码,调用直接 import 即可。使用 qrc 的 python 代码可以将资源注册到 QApplication 里面。不需要再读取资源数据,所有的组件都可以访问这些资源。

Spacer 妙用

Spacer 组件让 UI 更加紧凑。在缩放窗口的时候可以让 UI 直接没有间隙,观感好很多。

Layout 转组件

Layout 布局不属于 Widget 组件,无法设置样式。这个时候可以将 Layout 转成 QWidet 之类的组件实现进一步的操作。

Ctrl 复制组件

按住 Ctrl 键可以复制组件,有时候复杂布局也可以一并复制。

select ancestor 方便选择父级

组件比较复杂的情况,选择父组件会不方便,只能通过组件间的间隙进行选择。可以在右侧的大纲中选择,或者使用 select ancestor 命令

鼠标中间方便框选

本来用鼠标左键在空白区域拖拽,可以框选大量组件。但是组件比较多的话,没有空白区域,则可以用鼠标中键触发框选。

ctrl + R 预览窗口

Ctrl + R 快捷键可以快速打开一个运行状态的预览窗口。

Tab order 编辑

很少有用到。使用场景是输入框很多的时候,可以定义 Tab 键跳转到的组件

Edit Buddies 编辑功能

设置聚焦功能 ,用来通过 QLabel 的快捷键快速触发 QLineEdit 的聚焦。

官方链接:https://doc.qt.io/qt-6/designer-buddy-mode.html

QT Edit Buddies的理解:https://blog.csdn.net/technologyleader/article/details/82014028

2、Qt Designer 手册

Qt Designer 官网 手册:https://doc.qt.io/qt-6/qtdesigner-manual.html

Qt Designer是用于设计和构建图形用户界面(GUI)的Qt工具。可以以所见即所得 (WYSIWYG) 的方式编写和自定义窗口或对话框。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值