why does Qt Designer creates extra unnecessary waste code in PyQt5?

Viewed 142

I've created a simple form (without any functionality) which includes 2 widgets (a Push button and a LineEdit) first by manual coding then by using Qt Designer. I don't understand why Qt Designer creates so many extra codes that seem to be useless (to me) and makes it so complicated!. This is the code i've written manually:

import sys

from PyQt5.QtWidgets import QMainWindow,QPushButton,QApplication, QLineEdit

class Example(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
        def initUI(self):

            btn1 = QPushButton('Button1', self)
            btn1.move(30,50)
            btn1.resize(btn1.sizeHint())
            le = QLineEdit(self)
            le.move(100,100)
            self.setGeometry(300,300,290,150)
            self.setWindowTitle('Event Sender')
            self.show()

app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

And this is the output of Qt Designer UI file (as a python file)

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(417, 297)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(60, 130, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(210, 180, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 417, 20))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Event Sender"))
        self.pushButton.setText(_translate("MainWindow", "Button1"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Here are my Questions:

  1. Can some one please explain to me what is going on with the Qt Designer created file? It seems to me that it creates a seperate class just for the UI and then creates an instance of the QMainWindow class and then modifies this instance within the Ui_MainWindow() created instance. But in my code, i directly created a MainWindow class which inherits from QMainWindow and then set the UI up within that class

  2. Also what's the point of passing our QMainWindow instance here??: self.centralwidget = QtWidgets.QWidget(MainWindow) Why not self.centralwidget = QtWidgets.QWidget()?

  3. What is the point of these many extra code?!

1 Answers
  1. In Qt/C++ uic is a tool that allows you to convert a .ui to C++ code as an interface used to fill in some widget, that same concept is what pyuic tries to do, but in python. In your case fill in a QMainWindow or a class derived from it. But if the inheritance is implemented directly then it would be limited to the functionality that I initially thought about since, for example, it could not be used by a class inherited from QMainWidow. In conclusion: pyuic imitates what uic does, and uic aims to create an interface that fills in some Qt Widget.

  2. Both forms are equivalent and valid so there is no better way (that is totally debatable)

  3. Following that of (1) uic adds more things to handle the QObjects through the MOC such as the objectName(), it also implements a template for you to do translations (your application can be shown in different languages), in addition to using QMetaObject::connectSlotsByName() that allows automatic connections.

If you are going to use pyuic then do not pay attention to that code since you are not going to need to modify it, if you consider that it is unnecessary code then do not use it. Like any tool you have its pros and cons. If you consider that the implementation could improve then you could build your own tool that reads the .ui (which is an XML) and according to that information implement the code generation.

Related