将 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 对象没有代码完成,因为它们只在运行时加载;
这些都不是主要问题,但无论如何了解它们很重要。
是否有优势:
正在将其转换为 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 对象没有代码完成,因为它们只在运行时加载;
这些都不是主要问题,但无论如何了解它们很重要。