PyQt5提供了一个可视化图形工具Qt Designer,文件名为designer.exe。如果在电脑上找不到,可以用如下命令进行安装:
pip install PyQt5-tools
安装完毕后,可在如下目录找到此工具软件:%LOCALAPPDATA%\Programs\Python\Python39\Lib\site-packages\qt5_applications\Qt\bin\designer.exe
注意:%LOCALAPPDATA%通常代表C:\Users\你的用户名\AppData\Local\
VSCode添加外部工具
QtDesigner
打开PYQT Integration插件设置,搜索designer,将自己本地的designer.exe完整路径设置进去。
:::warning
注意,如果找不到designer.exe:
- Program路径要根据自己安装的PyQt5-tools路径设置(
pip install PyQt5-tools) - 安装的PyQt5-tools路径的取决于安装Python时的路径(
pip -V可以看到路径) - 如果用的是Python3.9.x,尝试用以下路径文件(先尝试在Win+R中能否打开):
%LOCALAPPDATA%\Programs\Python\Python39\Lib\site-packages\qt5_applications\Qt\bin\designer.exe
- 实在找不到,建议安装
everything.exe,全局搜索designer.exe位置 ::: 设置完成后,我们可以在.ui文件右键进行如下操作:
也可以在任意目录右键新建ui文件PyUIC
打开设置,过滤pyuic,按照下图填写:
- Cmd:
pyuic5 - Add Options:
--import-from=ui - Filepath:
Ui_${ui_name}.py

这个配置是为了右键.ui文件时,点击PYQT:Compile Form时,能生成对应.py文件
PyRCC
确保配置如下即可:
添加完成后,可在.qrc文件右键点击PYQT: Compile Resource,即可生成对应的.py资源文件。
加载UI文件模板代码
QMainWindow
我们通过可视化工具QtDesigner生成.ui文件后,需要在代码中加载并显示。可参照PyUIC部分教程进行转换。
使用xxx.ui生成xxx.py代码文件后,可使用如下代码进行加载。
注意,本例的ui相关文件都在ui目录下,即加载的ui包下的ui_main_window模块
"""PyQt5版GUI工具"""from PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *from ui.Ui_main_window import Ui_MainWindowimport sysclass MainWindow(QMainWindow):def __init__(self):super().__init__()# 创建对象self.ui = Ui_MainWindow()# 初始化内容self.ui.setupUi(self)# 初始化uiself.init_ui()def init_ui(self):passdef main():app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())if __name__ == '__main__':main()
目录结构如下
QWidget
from PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *import sys# 帮我们直接运行此文件时,可以加载到上级目录的ui包sys.path.append("../")from ui.Ui_my_widget import Ui_MyWidgetclass MyWidget(QWidget):def __init__(self, parent=None):super().__init__(parent)self.ui = Ui_MyWidget()self.ui.setupUi(self)self.init_ui()def init_ui(self):passif __name__ == '__main__':app = QApplication(sys.argv)window = MyWidget()window.show()sys.exit(app.exec_())
QDialog
from PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *from ui.Ui_serial_setting_dialog import Ui_SerialSettingDialogimport sysclass SerialSettingDialog(QDialog):def __init__(self, parent=None):super().__init__(parent)self.ui = Ui_SerialSettingDialog()self.ui.setupUi(self)# 可以通过此设置,固定对话框的大小self.setFixedSize(self.width(), self.height())self.initUi()self.baudrate = Nonedef initUi(self):passdef accept(self):super().accept()print("accept")# 读取当前波特率的设置值self.baudrate = self.ui.cb_bt.currentText()def reject(self):super().reject()print("reject")if __name__ == '__main__':app = QApplication(sys.argv)dialog = SerialSettingDialog()dialog.show()sys.exit(app.exec_())
常用知识点
修改标题图标
图片资源管理
图片按钮
background-color: transparent;border: none;
加载对话框
动态加载Widget
修改主题
qt-material
主题官网:https://github.com/UN-GCPDS/qt-material
使用方式:
安装:
pip install qt-material
代码:
from qt_material import apply_stylesheetapp = QtWidgets.QApplication(sys.argv)window = QtWidgets.QMainWindow()# setup stylesheetapply_stylesheet(app, theme='dark_teal.xml')# runwindow.show()app.exec_()
其他注意事项
事件被多次触发
问题描述:
如果自己给某个按钮或组件的信号设置槽函数,期待点击一次只触发一次,但是莫名被触发了多次。
原因分析:
参考文档介绍:QMetaObject - Qt for Python
原因很可能是因为槽函数命名问题。因为我们使用.ui文件生成的.py文件中,会执行一个如下的方法。帮我们根据组件的变量名绑定对应的槽函数:
QtCore.QMetaObject.connectSlotsByName(ChatRoomsWidget)
假设我们的对象有一个QPushButton类型的子对象,对象名称为button1。则自动connect且捕获按钮的clicked()信号的槽是:
def on_button1_clicked():
如果对象本身有一个通过[setObjectName()](https://doc.qt.io/qtforpython-6/PySide6/QtCore/QObject.html#PySide6.QtCore.PySide6.QtCore.QObject.setObjectName)设置的对象名称,它自己的信号也连接到它对应的槽。
解决办法:
换一个槽函数名称,或是按照官方规则直接声明槽函数
