Issue
Is there an advantage to:
Converting it to python pyside6-uic mainwindow.ui > ui_mainwindow.py and then
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())
vs. loading it directly like so: ?
ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file)
window.show()
I suppose the app will start faster/run faster if converted beforehand. Is there anything else to consider?
Solution
There are two main differences:
- in terms of loading, QUiLoader theoretically adds a bit of overhead because it has to build the ui everytime, meaning that it has to parse the XML file, create the node structure, and then create the UI with all its contents; the uic file, instead, directly creates the UI, skipping the first two steps above;
- QUiLoader can only create a new widget based on the UI file, while the uic method allows to use an already existing base widget, and the child widgets can be added to it;
The latter point is probably the most important: using QUiLoader you cannot directly use subclassing for the loaded UI.
For instance, if you create a main window in Designer, QUiLoader will return a new QMainWindow. You cannot (or, at least, you should not) do the following:
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)
And you should not even try to make the returned object as central widget, like the following:
self.setCentralWidget(window)
because the result would be to have a QMainWindow inside a QMainWindow, which is discouraged and unsupported, and might also create problems when using the standard features of a QMainWindow (typically, docks and toolbars).
The only alternative would be to create a basic form widget in Designer and use that as central widget, with the downside that menus, docks and toolbars have to be created by code.
For PySide, the only possibility that allows full subclassing is to use the pyside-uic method and then eventually use the multiple inheritance (but that's not a requirement, as composition is a valid alternative anyway):
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
On the other hand, PyQt provides the loadUi
function that actually does what setupUi
does, since the second argument is not the parent widget, but the widget itself, and the contents of the ui will be loaded into it:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi("mainwindow.ui", self)
As far as I know, PySide doesn't provide anything similar yet.
Note that loading the ui at runtime has two issues anyway, and for both bindings:
- there is no prior sanity checking, if the UI file is corrupted or invalid, or has unsupported features/properties due to version mismatch, it might not load properly or even crash;
- when using an IDE, there's no code completion for ui objects, since they are only loaded at runtime;
Those are not major issues, but it's important to be aware of them anyway.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.