Using UI files: switching from generating Python class to loading UI directly
-
Hi,
I've been using Qt Designer for creating windows and dialogs for my app, and I've been generating Python classes as suggested in the documentation:
pyside6-uic mainwindow.ui > ui_mainwindow.py
.
I found that it's also possible to load.ui
files directly and I decided to try that.I've ran into a problem that looks similar to this: https://stackoverflow.com/questions/50128293/pyside2-quiloader-returns-an-empty-window
I figured out how to resolve this when I launch the dialog separately, but it doesn't work when I call it from another window.
Here's what I'm doing in
my_dialog.py
:class MyDialog(QDialog): def __init__(self): super(MyDialog, self).__init__() # self.ui = Ui_myDialog() self.ui = QUiLoader().load('ui/my_dialog.ui') self.ui.show() # self.ui.setupUi(self) self.initialize() if __name__ == "__main__": app = QApplication(sys.argv) window = MyDialog() # window.show() sys.exit(app.exec_())
The commented code is from the generated class approach. Note that if I uncomment
window.show()
inmain()
it shows an empty window and my dialog.
Otherwise this "app" works fine by itself, but I need to open this dialog from another window.And when I do this like so:
my_dialog = MyDialog() if my_dialog.exec_(): <do something>
It shows 2 windows - my dialog and an empty window. Why is this, how to correct this?
Also, a more general question is: what's the best practice for working with
.ui
files? Is generating of Python classes preferred? What are the advantages and disadvantages of this approach?
I have no problem with generating Python classes, but this produces extra files and an extra step in the build process so using.ui
files directly seemed like a nice idea to me if I could easily switch to it.And finally, what's the best way for handling multiple windows/dialogs of the same class? Suppose I need to open unlimited instances of
MyDialog()
- what would be the best way to do this? Just callMyDialog().exec_()
multiple times?Thanks!
-
Hi,
exec is a blocking call so for the unlimited part, that won't do, you can however use open.
As for minimizing the use of files, you can also directly build your UI with code, that's one more layer removed.
Do not call show in your init, it's not the role of your widget to show itself, that's for the code handling it to decide.
-
Hi,
I've been using Qt Designer for creating windows and dialogs for my app, and I've been generating Python classes as suggested in the documentation:
pyside6-uic mainwindow.ui > ui_mainwindow.py
.
I found that it's also possible to load.ui
files directly and I decided to try that.I've ran into a problem that looks similar to this: https://stackoverflow.com/questions/50128293/pyside2-quiloader-returns-an-empty-window
I figured out how to resolve this when I launch the dialog separately, but it doesn't work when I call it from another window.
Here's what I'm doing in
my_dialog.py
:class MyDialog(QDialog): def __init__(self): super(MyDialog, self).__init__() # self.ui = Ui_myDialog() self.ui = QUiLoader().load('ui/my_dialog.ui') self.ui.show() # self.ui.setupUi(self) self.initialize() if __name__ == "__main__": app = QApplication(sys.argv) window = MyDialog() # window.show() sys.exit(app.exec_())
The commented code is from the generated class approach. Note that if I uncomment
window.show()
inmain()
it shows an empty window and my dialog.
Otherwise this "app" works fine by itself, but I need to open this dialog from another window.And when I do this like so:
my_dialog = MyDialog() if my_dialog.exec_(): <do something>
It shows 2 windows - my dialog and an empty window. Why is this, how to correct this?
Also, a more general question is: what's the best practice for working with
.ui
files? Is generating of Python classes preferred? What are the advantages and disadvantages of this approach?
I have no problem with generating Python classes, but this produces extra files and an extra step in the build process so using.ui
files directly seemed like a nice idea to me if I could easily switch to it.And finally, what's the best way for handling multiple windows/dialogs of the same class? Suppose I need to open unlimited instances of
MyDialog()
- what would be the best way to do this? Just callMyDialog().exec_()
multiple times?Thanks!
@midnightdim said in Using UI files: switching from generating Python class to loading UI directly:
Also, a more general question is: what's the best practice for working with .ui files? Is generating of Python classes preferred? What are the advantages and disadvantages of this approach?
I have no problem with generating Python classes, but this produces extra files and an extra step in the build process so using .ui files directly seemed like a nice idea to me if I could easily switch to it.For my own part, I much prefer generating the Python classes. You have a proper class with variables for the widgets all accessible at edit-time (e.g. code completion). With
QUiLoader()
yourself.ui
is just a black box. It is true that with Python/Creator there is an extra step in the build process (and has to be done manually whenever the.ui
changes, unless it has changed now for PySide6?), which is a pain, but I still feel it is worth it. Up to you. Compare the edit-time experiences. -
Hi,
exec is a blocking call so for the unlimited part, that won't do, you can however use open.
As for minimizing the use of files, you can also directly build your UI with code, that's one more layer removed.
Do not call show in your init, it's not the role of your widget to show itself, that's for the code handling it to decide.
@SGaist said:
Do not call show in your init, it's not the role of your widget to show itself, that's for the code handling it to decide.
Thanks, I commented it out. And now I don't understand how to use my dialog. I need to
_exec()
it to have theaccept()
method save the data, but I don't understand how to do this. If I useif my_dialog.ui.exec_(): <do something>
It shows the dialog, but
accept()
doesn't seem to be called when I submit it.
And if I usemy_dialog.exec_():
it shows an empty window.