PySide6、PyQt6、ui文件转py文件、Qt Designer 使用

发布时间 2023-04-25 14:04:25作者: hanfe1

QT 官网:https://www.qt.io/zh-cn/develop

1、PySide6*PyQt6、PyQt5*

PySide6、PySide2、PyQt5 都是基于 Qt 库,Qt 是一组 C++ 库和开发工具,包括图形用户界面、网络、线程、正则表达式、SQL 数据库、SVG、OpenGL、XML、用户和应用程序设置、定位和定位服务、短程通信( NFC 和蓝牙)、网页浏览、3D 动画、图表、3D 数据可视化以及与应用商店的交互。,有非常强大的图形界面开发库。

那么 PyQt5、PySide2、PySide6 三者有什么区别 ?

​ PyQt5 与 PySide2 基本上没有太大区别,都是在 Python 环境下的一套 Qt API库,但是 PySide2 由 Qt 官方维护,不过 pyside 掉了一段时间的队,其间 pyqt 火了,导致用 pyside 的人不多。不过 pyside 的优点在于有详细的官方维护的文档,PySide6 是 PySide2 的更新版本 【Qt 5 升级到 Qt 6 后,PySide2 也跟着升级到了 PySide6 (从2直接到6)】 ,二者几乎没什么差别。它们三者之间的代码转化也非常简单。所以推荐使用 PySide6 来创建基于 Qt6 的GUI 程序。

1.1 主要概念

Qt for Python 官方文档:https://doc.qt.io/qtforpython/contents.html

img

\1. 界面承载部分( 控件 )

\2. 界面框架部分 ( 布局 )

  • 主类:QLayout
  • 继承类:
    QGridLayout (网格布局)
    QBoxLayout(简单的上下布局)
    QStackedLayout (可切换widget的布局)
    FlowLayout

\3. 界面组件部分( 其实也是 Widget 类 )

  • button
  • label
  • 等等

\4. 界面样式部分

  • color
  • size
  • font
  • Icon

\5. 界面交互部分

  • action
  • event
  • signal
  • slot
  • connect

概念之间关系

  • QWidget 作为页面的主体,挂载在 layout (布局) 上,layout (布局) 可以添加页面的组件,通过 action(动作,类似于点击),event(事件),signal(信号),slot(信号槽),connect(动作绑定)产生交互
  • 通过样式类,类似于 Icon(图标),大小,颜色,字体等,修改界面的细节
  • widget 上需要有 layout,layout 可以 继续添加 widget,可以一直加下去

三个 窗口基类 ( QMainWindow、QWidget、QDialoh ) 的区别

在平常 qt 开发中,通常要写自己的窗口类,那么这个窗口类该继承自哪个类呢?

  • QWidget 继承于 QObject 和 QPaintDevice,
  • QDialog 和 QMainWindow 则继承于 QWidget。

下面就来看下三个窗口基类的区别:

  • \1. QMainWindow: QMainWindow类 提供一个有 "

    中央窗口部件、菜单栏、工具栏、状态栏

    " 的

    主应用程序窗口

    。QMainWindow 窗口经常被继承。QMainWindow 拥有自己的布局,可以使用 QMenuBar(菜单栏)、QToolBar(工具栏)、QStatusBar(状态栏)以及QDockWidget(悬浮窗体),布局有一个可由任何种类小窗口所占据的中心区域。

    img

  • \2. QWidget:QWidet 类是所有用户界面对象的基类,窗口部件是用户界面的一个基本单元,它从窗口系统接收鼠标,键盘和其他消息,并在屏幕上绘制自己。一个窗口部件可以被他的父窗口或者是其他窗口挡住一部分。

  • \3. QDialog:QDialog 类是对话框窗口的基类,对话框窗口主要用于短期任务以及和用户进行短期通讯的顶级窗口,QDialog可以是模态对话框或者是非模态对话框。QDialog 支持扩展并带有返回值,可以有默认按钮。QDialog也可以有一个QSizeGrip在它的右下角,使用setSizeGripEnabled()。

    模式对话框
    阻塞同一应用程序中其它可视窗口输入的对话框。模式对话框有自己的事件循环,用户必须完成这个对话框中的交互操作,并且关闭了它之后才能访问应用程序中的其它任何窗口。模式对话框仅阻止访问与对话相关联的窗口,允许用户继续使用其它窗口中的应用程序。

    显示模态对话框最常见的方法是调用其exec()函数,当用户关闭对话框,exec()将提供一个有用的返回值,并且这时流程控制继续从调用exec()的地方进行。通常情况下,要获得对话框关闭并返回相应的值,我们连接默认按钮,例如:”确定”按钮连接到accept()槽,”取消”按钮连接到reject()槽。另外我们也可以连接done()槽,传递给它Accepted或Rejected。

    非模式对话框
    和同一个程序中其它窗口操作无关的对话框。在文字处理中的查找和替换对话框通常是非模式的,允许用户同时与应用程序的主窗口和对话框进行交互。调用show()来显示非模式对话框,并立即将控制返回给调用者。

    如果隐藏对话框后调用show()函数,对话框将显示在其原始位置,这是因为窗口管理器决定的窗户位置没有明确由程序员指定,为了保持被用户移动的对话框位置,在closeEvent()中进行处理,然后在显示之前,将对话框移动到该位置。

    半模式对话框
    调用setModal(true)或者setWindowModality(),然后show()。有别于exec(),show() 立即返回给控制调用者。

    对于进度对话框来说,调用setModal(true)是非常有用的,用户必须拥有与其交互的能力,例如:取消长时间运行的操作。如果使用show()和setModal(true)共同执行一个长时间操作,则必须定期在执行过程中调用QApplication::processEvents(),以使用户能够与对话框交互(可以参考QProgressDialog)。

QMainWindow、QWidget、QDialoh 使用原则

  • 如果需要嵌入到其他窗体中,则基于 QWidget 创建。
  • 如果是顶级对话框,则基于 QDialog 创建。
  • 如果是主窗体,则基于 QMainWindow 创建。

QMainWindow 使用示例:

# -*- coding: utf-8 -*-
 
from PySide6.QtCore import (
    QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt
)
from PySide6.QtGui import (
    QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform
)
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QMenuBar, QPushButton,
    QSizePolicy, QStatusBar, QWidget, QPlainTextEdit
)
 
 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(700, 567)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.plainTextEdit = QPlainTextEdit(self.centralwidget)  # 添加的文本框
        self.plainTextEdit.setObjectName(u"plainTextEdit")
        self.plainTextEdit.setGeometry(QRect(90, 40, 521, 311))
        self.pushButton = QPushButton(self.centralwidget)  # 添加的按钮
        self.pushButton.setObjectName(u"pushButton")
        self.pushButton.setGeometry(QRect(330, 410, 75, 24))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 700, 22))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)
 
        self.retranslateUi(MainWindow)  # 调用下面的retranslateUi(self, MainWindow)函数。
 
        QMetaObject.connectSlotsByName(MainWindow)
 
    # setupUi
 
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(
            QCoreApplication.translate("MainWindow", u"\u81ea\u5b9a\u4e49\u7684\u6807\u9898\u680f", None))
        self.plainTextEdit.setPlaceholderText(QCoreApplication.translate("MainWindow", u"\u8bf7\u8f93\u5165", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u70b9\u51fb", None))
    # retranslateUi
 
 
# ================== 上面为 自动生成 的代码 ============================
# ================== 下面代码 使其显示出来  ============================
app = QApplication()
main_window = QMainWindow()
 
auto_ui_window = Ui_MainWindow()  # 实例化部件
auto_ui_window.setupUi(main_window)  # 调用setupUi()方法,并传入 主窗口 参数。
 
# 给按钮绑定调用函数。
# auto_ui_window.pushButton.clicked.connect(lambda x: print('点击了按钮'))
auto_ui_window.pushButton.clicked.connect(lambda x: auto_ui_window.plainTextEdit.appendPlainText("点击按钮"))
 
main_window.show()
app.exec()
pass

1.2 安装 PySide6

PySide6.QtWidgets:https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/index.html#module-PySide6.QtWidgets

PySide6 库还是非常大的,有将近 200M 左右,推荐使用国内的镜像来下载。PySide6 只支持Python 3.6+版本,另外特别注意的是,它只支持 64 位的 Python。

安装:pip install PySide6

安装完成后,python安装路径下 \Lib\site-packages 里找到 designer.exe。designer 是 Python 设计里面一个非常实用的工具,使得人们编写 qt 界面可以不仅仅是使用纯代码,而可以在可视化的基础上设置,非常方便。

img

Pycharm 配置 Pyside6 工具

运行 Pycharm,设置 ---> 外部工具 ---> 点击 +,添加 Pyside6_DesignerPyside6_UIC

  • 添加 Pyside6_Designer
    名称:Pyside6_Designer(可自己定义)
    程序:Pyside6-Designer 的安装路径。C:\Python39\Lib\site-packages\PySide6\designer.exe
    实参:不填
    工作目录: $FileDir$
  • 添加 Pyside6_UIC 名称:Pyside6_UIC(可自己定义)
    程序:pyside6-uic 的安装路径。C:\Python39\Scripts\pyside6-uic.exe
    实参:$FileName$ -o $FileNameWithoutExtension$.py

img

img

简单示例:

import sys
import random
from PySide6 import QtCore, QtWidgets, QtGui


class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]

        self.button = QtWidgets.QPushButton("Click me!")
        self.text = QtWidgets.QLabel("Hello World", alignment=QtCore.Qt.AlignCenter)

        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.magic)

    @QtCore.Slot()
    def magic(self):
        self.text.setText(random.choice(self.hello))


if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(800, 600)
    widget.show()

    sys.exit(app.exec())

*1.3 安装* *PyQt6*

如果使用 PySide6 进行开发,可以不用安装 PyQt6 或者 PyQt5

pip install PyQt6
pip install pyqt6-tools

安装完 "PyQt6-tools" 后,就可以在 Python 路径下的 Lib\site-packages\qt6_applications\Qt\bin 目录中找到 designer.exe 工具。

img

PyCharm 配置 *designer.exe*

  1. 在 " File ---> Settings ---> Tools ---> External Tools " 中点击 + 号,添加外部工具。
  2. 名称填写为 "Qt_Designer",这个名字可以随意填
  3. "程序" 中填入 "designer.exe" 的路径。
  4. "工作目录" 可以点击 输入框 上面的 + 号,选择预定义的目录变量,这里选择 $FileDir$

img

PyCharm 配置 Pyuic

PyUIC 主要是用来 " 将 Qt界面 转换成 py代码 "

  1. 在 " File ---> Settings ---> Tools ---> External Tools " 中点击 + 号,添加外部工具。
  2. 名称 填写为 "Py_UIC",这个名字可以随意填
  3. "程序" 中填入 "python.exe" 的路径。
  4. "实参" 中填入 -m PyQt6.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py 说明:-m 参数就是 "将 库模块 作为脚本运行",这里 库模块 是 PyQt6.uic.pyuic,
    查看 Lib\site-packages\PyQt5\uic 目录,发现 调用的是 pyuic.py
    -o 参数是 输出 文件名
  5. "工作目录" 中填入 $FileDir$

img

系统自定义 宏参数( 点击 宏参数 时 可以实时显示对应当前工程 的 值 ):

img

1.4 命令行 执行 *uic* *生成 py代码*

如果不填写 "实参" 这个选项时,在 Pycharm 中, 点击 .ui 文件 ---> 然后右键 ---> ExternalTools -> PyUIC 没法生成 .py 文件。只有通过命令行 生成 .py 文件:pyuic6.exe test.ui -o test.py。

img

只要安装对应的 QT ,就可以找到对应的 uic 可执行文件,直接命令行执行即可。

cmd 中打开 xxx.ui 所在路径例,然后执行:pyuic6 xxx.ui -o xxx.py

2、设计 UI 文件 并转换成 .py 文件

img

通过 Qt_Designer 设计 QT界面,然后保存为 "测试.ui" 文件

再通过 Py_UIC 会根据 "测试.ui" 文件 生成同名的 "测试.py" 文件。

如果上面 Py_UIC 配置正确,生成 .py 文件很简单:

  • .ui文件 ---> 右键 -> External Tools ---> Py_UIC,即可自动生成 py 文件

生成的 .py文件 中只有一个从 object 类继承的 Ui_MainWindow 的类,无法直接运行,如果想要运行,继续往下看。

3、运行 .py 文件,出现图形界面

这个时候直接运行 .py 文件,发现图形界面不会显示。

有两种方法可以显示界面。

方法 1 :直接运行这个 .py文件 就能看到界面的方式

PySide6

在文件末尾加上这一段代码:

if __name__ == "__main__":
    import sys
    from PySide6 import QtWidgets
    app = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件app
    MainWindow = QtWidgets.QMainWindow()    # 创建一个QMainWindow,用来装载你需要的各种组件、控件
    # MainWindow = QtWidgets.QWidget()        # 创建一个QMainWindow,用来装载你需要的各种组件、控件
    ui = Ui_MainWindow()          # ui是你创建的ui类的实例化对象
    ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
    MainWindow.show()       # 执行QMainWindow的show()方法,显示这个QMainWindow
    sys.exit(app.exec_())   # 使用exit()或者点击关闭按钮退出QApplication

完整代码:

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file '测试.ui'
##
## Created by: Qt User Interface Compiler version 6.3.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (
    QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt
)
from PySide6.QtGui import (
    QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform
)
from PySide6 import QtWidgets
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QMenuBar, QPushButton,
    QSizePolicy, QStatusBar, QWidget
)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        self.pushButton.setGeometry(QRect(150, 160, 211, 111))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 800, 22))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)

    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
    # retranslateUi


if __name__ == "__main__":
    import sys
    from PySide6 import QtWidgets

    app = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件app
    MainWindow = QtWidgets.QMainWindow()  # 创建一个QMainWindow,用来装载你需要的各种组件、控件
    # MainWindow = QtWidgets.QWidget()        # 创建一个QMainWindow,用来装载你需要的各种组件、控件
    ui = Ui_MainWindow()  # ui是你创建的ui类的实例化对象
    ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
    MainWindow.show()  # 执行QMainWindow的show()方法,显示这个QMainWindow
    sys.exit(app.exec_())  # 使用exit()或者点击关闭按钮退出QApplication

PyQT5

PyQt5基本功能:*****http://code.py40.com/1961.html*****

和 PySide6 差不多,完整示例代码( temp.py ):

# -*- coding: utf-8 -*-
# @Author  :
# @File    : temp.py
# @Software: PyCharm
# @description : XXX


from PyQt5 import QtCore, QtGui, QtWidgets
import sys


class Ui_MainWindow(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(70, 220, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(220, 220, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.checkBox = QtWidgets.QCheckBox(Form)
        self.checkBox.setGeometry(QtCore.QRect(70, 180, 141, 16))
        self.checkBox.setObjectName("checkBox")
        self.lineEdit = QtWidgets.QLineEdit(Form)
        self.lineEdit.setGeometry(QtCore.QRect(130, 56, 181, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(130, 110, 181, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(70, 60, 54, 12))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Form)
        self.label_2.setGeometry(QtCore.QRect(70, 110, 54, 12))
        self.label_2.setObjectName("label_2")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "取消"))
        self.pushButton_2.setText(_translate("Form", "确定"))
        self.checkBox.setText(_translate("Form", "记住用户名和密码"))
        self.label.setText(_translate("Form", "用户名:"))
        self.label_2.setText(_translate("Form", "密码:"))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件app
    MainWindow = QtWidgets.QMainWindow()    # 创建一个QMainWindow,用来装载你需要的各种组件、控件
    ui = Ui_MainWindow()          # ui是你创建的ui类的实例化对象
    ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
    MainWindow.show()       # 执行QMainWindow的show()方法,显示这个QMainWindow
    sys.exit(app.exec_())   # 使用exit()或者点击关闭按钮退出QApplication

程序云截图:

img

PyQT6

ImportError: DLL load failed while importing QtGui: 找不到指定的程序。

准备使用 PySide6,就没再查找具体原因。

方法 2:在 别的文件 中 调用 这个模块

通过 继承 QtWidgets.QWidget 或者 QtWidgets.QMainWindow 来实现

class MyForm(QMainWindow, Ui_MainWindow):

    def __init__(self):
        super(MyForm, self).__init__()
        self.setupUi(self)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    my_form = MyForm()
    my_form.setWindowTitle('my_form')
    my_form.show()
    sys.exit(app.exec())
    pass

生成的 Python 文件只有定义主窗口以及其控件的代码,并没有程序入口的代码。为了秉持视图与逻辑分离的原则,可以再编写一个新的脚本来调用这个文件,并且创建一个窗口。这个和 方法 1 中的 右键 run 就能显示界面的方式 并不冲突,只是要在别的文件中调用这个模块。调用文件的写法( main.py ):

# -*- coding: utf-8 -*-
# @Author  : 
# @File    : main.py
# @Software: PyCharm
# @description : XXX


import sys
from temp import Ui_MainWindow
from PyQt5 import QtWidgets


# 这个类继承界面UI类
class MyWindow1(QtWidgets.QWidget, Ui_MainWindow):
    def __init__(self):
        super(MyWindow1, self).__init__()
        self.setupUi(self)


# 这个类继承界面UI类
class MyWindow2(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyWindow2, self).__init__()
        self.setupUi(self)


# 调用show
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    form_1 = MyWindow1()
    form_1.setWindowTitle('form_1')
    form_1.show()

    form_2 = MyWindow2()
    form_2.setWindowTitle('form_2')
    form_2.show()

    sys.exit(app.exec_())

被调用文件( temp.py )和上面 temp.py 文件一样。承了Ui_MainWindow类,使用其构造方法构造主窗口,并定义了程序的入口,通过创建 QApplication 对象来创建Qt窗口

程序运行截图:

img

4、PyQT5 之 Qt Designer 介绍与入门

在 PyQt 中编写 UI 界面可以直接通过代码来实现,也可以通过 Qt Designer 来完成。Qt Designer的设计符合 MVC 的架构,其实现了视图和逻辑的分离,从而实现了开发的便捷。Qt Designer中的操作方式十分灵活,其通过拖拽的方式放置控件可以随时查看控件效果。

Qt Designer 随 PyQt5-tools 包一起安装,其安装路径在 "Python安装路径\Lib\site-packages\PyQt5\Qt5\bin" 下。若要启动 Qt Designer 可以直接到上述目录下,

  • 双击 designer.exe打开 Qt Designer;
  • 或将上述路径加入环境变量,在命令行输入designer 打开;
  • 或在 PyCharm 中将其配置为外部工具打开。

Qt Designer 生成的.ui文件(实质上是XML格式的文件)可以通过 pyuic5 工具转换成 .py 文件。

Qt Designer 界面简介

点击 QtDesigner 打开 QtDesigner 的界面,弹出如下图所示的窗口。

img

创建新的 Form 给出了5个模板,其中 WidgetMainWindow 最为常用。这里创建一个 MainWindow 。上面界面的最左侧菜单为 Widget Box,Widget Box 中包含所有 Widget 组件,从左侧的 Widget Box 中拖拽出诸如 Button、View 和 Input 等组件到中间的窗口中。

点击 菜单栏 ---> 窗体 ---> 预览 ( 快捷键为Ctrl+R ) ,可以预览设计好的界面,也可以 "预览与" 来选择在相应的主题风格下预览。

现在拖拽一个 Label 与 Button 进入主窗口(Main Window)。

img

此时在右上角的 Object Inspector(对象检查器)中可以看到主窗口中的已放置的对象( label 与pushButton )以及其相应地 Qt 类。以 Label 为例,点击 Main Window 中的 label 或是在 Object Inspector 中选取 label 后,查看右侧的一块区域 Property Editor( 属性编辑器 ),其主要包含属性有如下:

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

PS:将 minimumSize 和 maximumSize 设为一样的数值之后,则窗口的大小固定。

最右下角的部分则为 Resource Browser(资源浏览器),资源浏览器中可以添加相应地如图片素材,作为 Label 或 Button 等控件的 背景图片 等。

Qt Designer 的 UI 文件

使用 Qt Designer 设计程序界面,然后保存的文件为 .ui格式的文件。通过保存并使用记事本等软件打开,可以看到.ui文件的内容如下:

从 .ui文 件的第一行我们便能看出,其实质是一个XML文件。ui文件中存放了在主窗口中的一切控件的相关属性。使用 XML 文件来存储UI文件,具有高可读性和移植性,因此我们可以方便地将.ui文件转换到.py文件,从而使得我们可以使用 Python 语言在设计的 GUI 上面编程。

5、PyQT5 速成教程 --- 3 布局管理

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 Designer中,在工具箱中最上方可以看到有4种布局。分别是

  • 垂直布局
  • 水平布局
  • 网格布局
  • 表单布局

img

布局名称 布局含义
垂直(Vertical)布局 布局内的控件按照从上到下的顺序纵向排列
水平(Horizontal)布局 布局内的控件按照从左到右的顺序横向排列
栅格(Grid)布局,也 叫网格布局 将控件放入栅格中,然后划分成若干行与若干列,并且将每个窗口控件放在合适的单元中
表单(Form)布局 控件以两列布局在表单中,左列包含标签,右列包含输入控件

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

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

通过 布局管理器 进行布局

在左侧的工具箱中随意拖动一些控件,例如:按钮、标签、输入框等控件 到 主窗口中。

img

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

img

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

img

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

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

img

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

img

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

img

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

img

布局管理 生成 代码

把布局保存为.ui文件,并使用 PyUIC 转换为 .py 文件。

使用 容器 进行布局

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

img

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

img

选中 Frame 中空白地方,点击右键 -> 布局 -> 水平布局,则会自动水平排列 Frame 中的控件。文章来源站点https://www.yii666.com/

img

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

绝对布局

前面学习了布局管理器。但是最简单的布局则是之间输入控件的 Geometry 属性值。

img

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

名称 含义
X 290 控件的最左上角距离主窗口的左侧290px
Y 140 控件的最左上角距离主窗口的上方140px
Width 93 按钮的宽度为93px
Height 28 按钮的高度为23px

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

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

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

6、Designer 实战 --- 计算器界面

使用网格布局(Grid Layout)

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

img

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

img

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

img

使用 Spacer 增加空白间隔

img

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

img

通过在空白地方右键,对主窗口使用Vertical Lay Out。文章来源地址https://www.yii666.com/blog/338339.html

img

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

img

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

img

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

img

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

sizePolicy 尺寸策略

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

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

img

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

img

参数说明:

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

img

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

img

版权声明:本文内容来源于网络,版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。文本页已经标记具体来源原文地址,请点击原文查看来源网址,站内文章以及资源内容站长不承诺其正确性,如侵犯了您的权益,请联系站长如有侵权请联系站长,将立刻删除