将 ui 文件转换为 Python 代码与直接加载相比有何优势?

What is the advantage of converting a ui file to Python code vs loading it directly?

是否有优势:

正在将其转换为 python pyside6-uic mainwindow.ui > ui_mainwindow.py 然后

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())

对比像这样直接加载它:?

ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)

loader = QUiLoader()
window = loader.load(ui_file)
window.show()

我想如果事先进行转换,应用程序将 faster/run 启动得更快。 还有什么需要考虑的吗?

有两个主要区别:

  • 在加载方面,QUiLoader 理论上会增加一些开销,因为它每次都必须 build ui,这意味着它必须解析 XML 文件,创建节点结构,然后创建 UI 及其所有内容; uic 文件直接创建 UI,跳过上面的前两个步骤;
  • QUiLoader 只能根据UI 文件创建new widget,而uic 方法允许使用已经存在的base widget,子widgets可以加入其中;

后一点可能是最重要的:使用 QUiLoader 不能直接对加载的 UI.

使用子类化

例如,如果您在 Designer 中创建一个主 window,QUiLoader 将 return 一个 new QMainWindow。您不能(或者至少,您不应该)执行以下操作:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        ui_file = QFile("mainwindow.ui")
        ui_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        window = loader.load(ui_file, self)

而且您甚至不应该尝试将 returned 对象作为中央小部件,如下所示:

        self.setCentralWidget(window)

因为结果将是在 QMainWindow 内部 QMainWindow,这是不鼓励和不受支持的,并且在使用 QMainWindow 的标准功能时也可能产生问题(通常,停靠栏和工具栏)。

唯一的选择是在 Designer 中创建一个基本的表单小部件并将其用作中心小部件,缺点是必须通过代码创建菜单、停靠栏和工具栏。

对于 PySide,允许完全子类化的唯一可能性是使用 pyside-uic 方法,然后最终使用多重继承(但这不是 requirement,因为组合无论如何都是一个有效的选择):

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

另一方面,PyQt 提供了 loadUi 函数,它实际上做了 setupUi 所做的事情,因为第二个参数不是父部件,而是部件本身,以及ui 将加载 中:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        uic.loadUi("mainwindow.ui", self)

据我所知,PySide 还没有提供类似的东西。

请注意,无论如何,在运行时加载 ui 有两个问题,对于两个绑定:

  • 没有事先的健全性检查,如果UI文件损坏或无效,或者由于版本不匹配而不受支持features/properties,它可能无法正确加载甚至崩溃;
  • 使用 IDE 时,ui 对象没有代码完成,因为它们只在运行时加载;

这些都不是主要问题,但无论如何了解它们很重要。