使用.ui
文件从Designer或QtCreator与QUiLoader
和pyside6-uic
¶
本页描述了如何使用
Qt Widgets Designer 为您的 Qt for Python 项目创建基于 Qt Widgets 的图形界面。
Qt Widgets Designer 是一个图形用户界面设计工具,可以作为独立的二进制文件(pyside6-designer
)使用,也可以嵌入到
Qt Creator IDE 中。在 Qt Creator 中的使用描述见
Using Qt Widgets Designer。

设计存储在.ui
文件中,这是一种基于XML的格式。它将在项目构建时通过pyside6-uic工具转换为填充小部件实例的Python或C++代码。
要在Qt Creator中创建一个新的Qt设计表单,请选择
文件/新建 文件 或 项目
,并选择“主窗口”作为模板。将其保存为
mainwindow.ui
。在centralwidget的中心添加一个QPushButton
。
您的文件 mainwindow.ui
应该看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>110</x>
<y>80</y>
<width>201</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
现在我们准备决定如何从Python中使用UI文件。
选项A:生成一个Python类¶
与UI文件交互的标准方法是生成一个Python类。这要归功于pyside6-uic
工具。要使用此工具,您需要在控制台上运行以下命令:
pyside6-uic mainwindow.ui -o ui_mainwindow.py
我们将命令的所有输出重定向到一个名为ui_mainwindow.py
的文件中,该文件将直接导入:
from ui_mainwindow import Ui_MainWindow
现在要使用它,我们应该为我们的部件创建一个个性化的类来设置这个生成的设计。
为了理解这个想法,让我们看一下整个代码:
import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtCore import QFile
from ui_mainwindow import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
从之前的例子中已经知道if语句中的内容,我们的新基础类只包含两行新代码,负责从UI文件加载生成的python类:
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
注意
每次对UI文件进行更改后,您都必须再次运行pyside6-uic
。
选项 B:直接加载¶
要直接加载UI文件,我们需要从QtUiTools模块中获取一个类:
from PySide6.QtUiTools import QUiLoader
QUiLoader
允许我们动态加载 ui 文件 并立即使用它:
ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file)
window.show()
这个示例的完整代码如下所示:
# File: main.py
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 = "mainwindow.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())
然后要执行它,我们只需要在命令提示符下运行以下内容:
python main.py
注意
QUiLoader
使用 connect()
调用,将函数签名作为字符串参数用于信号/槽连接。
因此,它无法处理来自用 Python 编写的自定义小部件的 Python 类型,如 str
或 list
,因为这些类型在内部映射到不同的 C++ 类型。
Qt Widgets Designer中的自定义小部件¶
Qt Widgets Designer 能够使用用户提供的(自定义)部件。 它们显示在部件框中,并且可以像 Qt 的部件一样拖放到表单上(参见 使用自定义部件与 Qt Widgets Designer )。通常,这需要将部件实现为 Qt Widgets Designer 的插件,使用 C++ 编写并实现其 QDesignerCustomWidgetInterface 。
Qt for Python 为此提供了一个简单的接口,类似于
registerCustomWidget()
。
小部件需要作为一个Python模块提供,如WigglyWidget示例(文件wigglywidget.py
)或任务菜单扩展示例(文件tictactoe.py
)所示。
在Qt Widgets Designer中注册此功能是通过提供一个名为register*.py
的注册脚本并将路径类型的环境变量PYSIDE_DESIGNER_PLUGINS
指向该目录来完成的。
注册脚本的代码如下所示:
# File: registerwigglywidget.py
from wigglywidget import WigglyWidget
import QtDesigner
TOOLTIP = "A cool wiggly widget (Python)"
DOM_XML = """
<ui language='c++'>
<widget class='WigglyWidget' name='wigglyWidget'>
<property name='geometry'>
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name='text'>
<string>Hello, world</string>
</property>
</widget>
</ui>
"""
QPyDesignerCustomWidgetCollection.registerCustomWidget(WigglyWidget, module="wigglywidget",
tool_tip=TOOLTIP, xml=DOM_XML)
QPyDesignerCustomWidgetCollection 提供了 QDesignerCustomWidgetCollectionInterface 的实现,将自定义小部件暴露给Qt Widgets Designer,并提供了用于注册类型或添加 QDesignerCustomWidgetInterface 实例的静态便捷函数。
函数
registerCustomWidget()
用于向Qt Widgets Designer注册一个小部件类型。在简单的情况下,它可以像QUiLoader.registerCustomWidget()
这样使用。它接受自定义小部件类型和一些可选的关键字参数,这些参数传递的值对应于
QDesignerCustomWidgetInterface的getters:
当通过启动器 pyside6-designer
启动 Qt Widgets Designer 时,自定义小部件应该在小部件框中可见。
对于高级用法,也可以将类QDesignerCustomWidgetInterface的实现传递给函数,而不是类型到addCustomWidget()
。这在taskmenuextension示例中显示,其中为自定义小部件注册了自定义上下文菜单。该示例是对应的C++ 任务菜单扩展示例的移植。
Qt Widgets Designer 插件故障排除¶
必须使用启动器
pyside6-designer
。独立的 Qt Widgets Designer 将无法加载插件。菜单项 帮助/关于插件 会弹出一个对话框,显示找到的插件和可能的加载错误信息。
检查控制台或Windows调试视图以获取更多错误信息。
由于Python输出的缓冲,错误信息可能只在Qt Widgets Designer终止后出现。
在构建 Qt for Python 时,请确保设置
--standalone
选项,以便正确安装插件。