@Brownbear: Grrr, jetzt habe ich das Video angesehen — was für eine verschwendete Zeit. Du gingst davon aus ich hätte es nicht gesehen — warum? Denn ich weiss nicht mehr als vorher und dementsprechend ändert sich da auch nichts an meiner Einstellung oder Argumentation gegen das generieren von Quelltext wenn man diesen Schritt auch leicht umgehen kann.
UI-Dateien sind XML was mit Python nichts zu tun hat, wird irgendwie so gesagt als wenn das schlecht wäre. UI-Dateien haben halt auch nicht viel mit Programmcode zu tun, darum ist das überhaupt nicht schlecht, dass das kein Programmquelltext ist. Grössere Layouts will man auch gar nicht als Quelltext lesen, weil das massiv unübersichtlich ist, und ja auch der Grund warum man überhaupt den Designer verwenden will.
Wobei die Aussage in dem Video, dass man das, was man da an generiertem Code sieht, alles zu Fuss schreiben müsste, natürlich auch nicht stimmt. Da ist viel das eigentlich unnötig ist, und in Code hat man im Gegensatz zum Designer auch die Möglichkeit *Code* zu schreiben und zu nutzen, also Funktionen/Methoden und Schleifen, damit man sich wiederholende Sachen nicht tatsächlich als Code schreiben muss. Ich habe das Beispiel aus dem Video mal im Designer nachgestellt (ordentlich mit Layouts statt mit absolten Positions- und Grössenangaben) und das ist der mit pyuic5 generierte Quelltext:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(186, 159)
self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.horizontal_radio_buttons = QtWidgets.QGroupBox(Dialog)
self.horizontal_radio_buttons.setObjectName("horizontal_radio_buttons")
self.verticalLayout = QtWidgets.QVBoxLayout(self.horizontal_radio_buttons)
self.verticalLayout.setObjectName("verticalLayout")
self.radioButton = QtWidgets.QRadioButton(self.horizontal_radio_buttons)
self.radioButton.setObjectName("radioButton")
self.verticalLayout.addWidget(self.radioButton)
self.radioButton_2 = QtWidgets.QRadioButton(self.horizontal_radio_buttons)
self.radioButton_2.setObjectName("radioButton_2")
self.verticalLayout.addWidget(self.radioButton_2)
self.radioButton_3 = QtWidgets.QRadioButton(self.horizontal_radio_buttons)
self.radioButton_3.setObjectName("radioButton_3")
self.verticalLayout.addWidget(self.radioButton_3)
self.horizontalLayout.addWidget(self.horizontal_radio_buttons)
self.vertical_radio_buttons = QtWidgets.QGroupBox(Dialog)
self.vertical_radio_buttons.setCheckable(False)
self.vertical_radio_buttons.setObjectName("vertical_radio_buttons")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.vertical_radio_buttons)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.radioButton_4 = QtWidgets.QRadioButton(self.vertical_radio_buttons)
self.radioButton_4.setObjectName("radioButton_4")
self.verticalLayout_2.addWidget(self.radioButton_4)
self.radioButton_5 = QtWidgets.QRadioButton(self.vertical_radio_buttons)
self.radioButton_5.setObjectName("radioButton_5")
self.verticalLayout_2.addWidget(self.radioButton_5)
self.radioButton_6 = QtWidgets.QRadioButton(self.vertical_radio_buttons)
self.radioButton_6.setObjectName("radioButton_6")
self.verticalLayout_2.addWidget(self.radioButton_6)
self.horizontalLayout.addWidget(self.vertical_radio_buttons)
self.verticalLayout_3.addLayout(self.horizontalLayout)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout_3.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept) # type: ignore
self.buttonBox.rejected.connect(Dialog.reject) # type: ignore
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Main Dialog"))
self.horizontal_radio_buttons.setTitle(_translate("Dialog", "horizontal"))
self.radioButton.setText(_translate("Dialog", "links"))
self.radioButton_2.setText(_translate("Dialog", "mitte"))
self.radioButton_3.setText(_translate("Dialog", "unten"))
self.vertical_radio_buttons.setTitle(_translate("Dialog", "vertikal"))
self.radioButton_4.setText(_translate("Dialog", "oben"))
self.radioButton_5.setText(_translate("Dialog", "mitte"))
self.radioButton_6.setText(_translate("Dialog", "unten"))
Alles anzeigen
Den Wust will doch kein Mensch wirklich lesen. Erst recht nicht wenn die GUI nicht mehr so klein und einfach aufgebaut ist.
Von Hand geschrieben sähe das so aus *und* hat auch gleich die Reaktion auf die Auswahl eines Radiobutton mit etwas sprechender Ausgabe als einfach nur nummeriert von 1 bis 6:
#!/usr/bin/env python3
import sys
from functools import partial
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QDialogButtonBox,
QGroupBox,
QHBoxLayout,
QRadioButton,
QVBoxLayout,
)
def main():
app = QApplication(sys.argv)
dialog = QDialog()
dialog_layout = QVBoxLayout(dialog)
layout = QHBoxLayout()
for direction, texts in [
("horizontal", ["links", "mitte", "rechts"]),
("vertikal", ["oben", "mitte", "unten"]),
]:
group_box = QGroupBox(direction)
button_layout = QVBoxLayout(group_box)
for text in texts:
button_layout.addWidget(
QRadioButton(
text, clicked=partial(print, f"{direction}: {text}")
)
)
layout.addWidget(group_box)
dialog_layout.addLayout(layout)
dialog_layout.addWidget(
QDialogButtonBox(
QDialogButtonBox.Cancel | QDialogButtonBox.Ok,
accepted=dialog.accept,
rejected=dialog.reject,
)
)
dialog.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Alles anzeigen
Und das ganze noch mal mit laden der .ui-Datei:
#!/usr/bin/env python3
import sys
from functools import partial
from pathlib import Path
from PyQt5.QtWidgets import QApplication, QRadioButton
from PyQt5.uic import loadUi
SELF_PATH = Path(__file__).parent
def main():
app = QApplication(sys.argv)
dialog = loadUi(SELF_PATH / "test.ui")
for box in [
dialog.horizontal_radio_buttons,
dialog.vertical_radio_buttons,
]:
direction = box.title()
for button in box.findChildren(QRadioButton):
button.clicked.connect(
partial(print, f"{direction}: {button.text()}")
)
dialog.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Alles anzeigen
Zurück zum Video: Importe so abzukürzen ist furchtbar und auch bei anderen Namen wird viel zu viel abgekürzt. (`wnd` für `window`, Modulname `mqt`, `mgui` für?) Aussagekräftige Namen sind ”Rotz” den man nicht immer schreiben will, und `rb1` bis `rb6` sind vertretbare Namen‽ ? Ja nee, nicht wirklich.
Alles auf Modulebene und aus der generierten Klasse, die eigentlich als Mixin gedacht ist, wird ein Exemplar erstellt. Argh. Er sagt ja selbst er versteht nicht so ganz was da passiert. Dann sollte man vielleicht auch keine Erklärvideos dazu machen wo man eine falsche Verwendung zeigt. ?