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

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

用 Python 编写安卓 APK:https://zhuanlan.zhihu.com/p/398126847

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

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(悬浮窗体),布局有一个可由任何种类小窗口所占据的中心区域。

  • 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)# setupUidef 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 界面可以不仅仅是使用纯代码,而可以在可视化的基础上设置,非常方便。

Pycharm 配置 Pyside6 工具

运行 Pycharm,设置 ---> 外部工具 ---> 点击 +,添加 Pyside6_Designer 和 Pyside6_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

简单示例:

import sys
import random
from PySide6 import QtCore, QtWidgets, QtGuiclass 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 工具。

PyCharm 配置 designer.exe

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

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$ 

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

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

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

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

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

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

通过 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 sysfrom PySide6 import QtWidgetsapp = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件appMainWindow = QtWidgets.QMainWindow()    # 创建一个QMainWindow,用来装载你需要的各种组件、控件# MainWindow = QtWidgets.QWidget()        # 创建一个QMainWindow,用来装载你需要的各种组件、控件ui = Ui_MainWindow()          # ui是你创建的ui类的实例化对象ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindowMainWindow.show()       # 执行QMainWindow的show()方法,显示这个QMainWindowsys.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)# setupUidef retranslateUi(self, MainWindow):MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))# retranslateUiif __name__ == "__main__":import sysfrom PySide6 import QtWidgetsapp = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件appMainWindow = QtWidgets.QMainWindow()  # 创建一个QMainWindow,用来装载你需要的各种组件、控件# MainWindow = QtWidgets.QWidget()        # 创建一个QMainWindow,用来装载你需要的各种组件、控件ui = Ui_MainWindow()  # ui是你创建的ui类的实例化对象ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindowMainWindow.show()  # 执行QMainWindow的show()方法,显示这个QMainWindowsys.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 : XXXfrom PyQt5 import QtCore, QtGui, QtWidgets
import sysclass 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.translateForm.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,也就是你要开发的软件appMainWindow = QtWidgets.QMainWindow()    # 创建一个QMainWindow,用来装载你需要的各种组件、控件ui = Ui_MainWindow()          # ui是你创建的ui类的实例化对象ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindowMainWindow.show()       # 执行QMainWindow的show()方法,显示这个QMainWindowsys.exit(app.exec_())   # 使用exit()或者点击关闭按钮退出QApplication

程序云截图:

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 sysapp = 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 : XXXimport 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窗口

程序运行截图:

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 的界面,弹出如下图所示的窗口。

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

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

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

此时在右上角的 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种布局。分别是

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

布局名称布局含义
垂直(Vertical)布局布局内的控件按照从上到下的顺序纵向排列
水平(Horizontal)布局布局内的控件按照从左到右的顺序横向排列

栅格(Grid)布局,

也 叫网格布局

将控件放入栅格中,然后划分成若干行与若干列,并且将每个窗口控件放在合适的单元中
表单(Form)布局控件以两列布局在表单中,左列包含标签,右列包含输入控件

在 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 属性的四个值。通过以上的方法,我们可以对任何一个控件进行布局。

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

使用网格布局(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 与下面的键盘之间的间距变小了。

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

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

相关文章

用visio反向工程画oracle数据库表的结构图

步骤: 1、数据库----反向工程 2、在反向工程向导中选择--设置--然后选择---Microsoft--ODBC-for--oracle 3、新建数据源---选择用户数据源----Microsoft--ODBC-for--oracle4、输入用户名和数据库名5、输入数据库密码---选择需要绘制的表转载于:https://www.cnblogs.com/kokyu/a…

Mockito—参数匹配~任意

import org.mockito.Mockito;Test public void withUnspecifiedArguments() {List list Mockito.mock(List.class);//匹配任意参数Mockito.when(list.get(org.mockito.Matchers.anyInt())).thenReturn(1);//测试Assert.assertEquals(1, list.get(1));Assert.assertEquals(1, l…

该如何对「半监督学习算法」实际性应用进行评估?Google给出了新答案

原文来源:arXiv 作者:Avital Oliver、Augustus Odena、Colin Raffel、Ekin D. Cubuk、Ian J. Goodfellow「雷克世界」编译:KABUDA、EVA半监督学习(Semi-supervised learning,SSL)提供了一个强大的框架&…

Python PyQt5 教程

PyQt5教程 :http://code.py40.com/face 教程翻译自:http://zetcode.com/gui/pyqt5/ PyQt5 的 核心API 以及 扩展应用(CSDN 学院收费视频):https://edu.csdn.net/course/play/9870/222942 pyqt5 - 对文本样式进行操作&…

Silverlight中全屏处理

Silverlight插件支持全屏模式,这个没什么好说的,只需要用设置IsFullScreen属性即可,问题在于全屏模式中,尽管屏幕变大了,但是页面中的控件并未相应的变大,下面是我在网上找到的解决这个问题的两种方式。 第…

Mockito—参数匹配

mock方法时,总会因场景不同,调整参数的匹配情况。比如:某个参数是为了在数据库进行模糊查询的;或则精确匹配时,引用类型参数未实现equals方法。这时候就需要mock方法时,进行不同匹配。 1. 参数精确匹配 Ma…

人工智能的过去、现在和未来

来源: 人工智能和大数据 作者: 腾讯 AI Lab 主任 张潼在回答人工智能达到了什么程度这个问题之前,需先了解人工智能的概念是什么?人工智能(Artificial Intelligence,AI)是指计算机像人一样拥有智…

Python3 函数注释: 参数 中 的 冒号 与 箭头

From:https://blog.csdn.net/liang19890820/article/details/74264380 简述 在 Python 3.x 中,增加了一个新特性 - 函数注释(Function Annotations),顾名思义,可做为函数额外的注释来用。 函数注释是一个可…

软件生存周期文档系列 之 6.用户操作手册

6 用户操作手册 6.1 引言 6.1.1 编写目的 6.1.2 项目背景 6.1.3 参考资料(包括项目计划任务书、合同或批文;项目开发计划;需求规格说明书;概要设计说明书;详细说明书;测试计划等&am…

Dom4j完整教程~DOM4J简介

DOM4J是 dom4j.org 出品的一个开源 XML 解析包。DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP。 DOM4J 使用起来非常简单。只要你了解基本的 XML-DOM 模型,就能使用。 Dom:把整个文档作为一个对象。 DO…

除了芯片 我们还应关注哪些核心技术

来源:传感器技术(公众号)最近的“中兴封杀”事件,让国人深深领略了缺少核心技术给企业乃至行业和国家带来的巨痛。除了我们知道的芯片技术之外,还有哪些核心技术需要我们重点关注呢?超级计算终端 超级计算终…

Python PyInstaller 安装 和 使用教程( 打包生成 exe )

From:http://c.biancheng.net/view/2690.html Python zipapp打包教程:http://c.biancheng.net/view/2687.html 在创建了独立应用(自包含该应用的依赖包)之后,还可以使用 PyInstaller 将 Python 程序生成可直接运行的程…

Dom4j完整教程~XML文档简单操作

读取XML文档: 读写XML文档主要依赖于org.dom4j.io包,有DOMReader和SAXReader两种方式。因为利用了相同的接口,它们的调用方式是一样的。 public static Document load(String filename) { Document document null; try { SAXReader sax…

Yann LeCun:距离“真正的” AI,我们还缺什么?

来源: AI科技大本营(ID;rgznai100)GMIC Beijing 2018 大会第一天,首个演讲者是 Facebook 首席 AI 科学家 Yann LeCun。他讲述了关于深度学习的最新研究成果,同时也描述了深度学习的未来,以及机…

Python 使用 smtp ssl 模式 发送邮件与附件

参考 : 发送邮件简单入门 ( 以qq邮箱,163邮箱为例 ) :https://blog.csdn.net/qq_38661599/article/details/81013834 smtp ssl 模式 发送邮件 与 附件:https://www.cnblogs.com/SunshineKimi/p/10629342.html Python…

Unity.Interception System (2.0)

转载于:https://www.cnblogs.com/artech/archive/2010/08/27/1810010.html

PyQt5 快速开发 与 实战

From:https://blog.csdn.net/jia666666/category_9278208.html PyQt5 信号 与 槽 信号与槽的入门应用(一):https://blog.csdn.net/jia666666/article/details/81774175 信号与槽的再细分(二):ht…

Flex 流式布局 之 滚动条篇

Flex 流式布局 之 滚动条篇 flex 框架支持流式布局,什么是流式布局呢,就是在运行时对象的大小是未知的,它可能需要由他的内容(childs)或由它的容器来决定它的实际大小。flex 中有两种流式一种就是 百分比形式的(percentWidth),还…

卷积神经网络为什么能称霸计算机视觉领域?

来源:图灵人工智能摘要:在机器视觉和其他很多问题上,卷积神经网络取得了当前最好的效果,它的成功促使我们思考一个问题,卷积神经网络为什么会这么有效?在本文中,将为大家分析卷积神经网络背后的…

Dom4j完整教程~Document对象相关

读取XML文件,获得document对象. SAXReader reader new SAXReader(); Document document reader.read(new File("input.xml")); 解析XML形式的文本,得到document对象. String text "<members></members>"; Document document Doc…