how to separate the ui and implementation in PyQT?

inheritance, pyqt, pyside, python, user-interface

Solution

It's not a good idea to change the UI file as it will be regenerated every time you update the UI in Qt Creator and any changes will be lost.

Instead, make another UI class that calls the auto generated file for you (and there are other designs for defining the UI class, as ekhumoro pointed out):

class Prog(QtGui.QMainWindow):
    def __init__(self):
        super().__init__();
        self.ui = Ui_Form()
        self.ui.setupUi(self)

if __name__=='__main__':
    Program =  QtWidgets.QApplication(sys.argv)
    MyProg = Prog()
    MyProg.show()
    sys.exit(Program.exec_())

In this way, an instance of the class `Prog` is passed into the `setupUi` method (`self` is the reference the `Prog` instance has to itself). Within the `setupUi` method this reference is called `Form`, and is used many times, as can be seen in your code:

Form.resize(400, 300)
self.pushButton = QtWidgets.QPushButton(Form)

`Form` is named such probably because you set `objectName` to be `Form` in Qt Creator. However, regardless of what it's called this is a reference to the parent widget that the auto generated file needs to setup. Conceptually it would make more sense if you named them the same, e.g. rename both your `Prog` class and the UI `objectName` to something like `ProgramUI`.

Problem

I have a question while i am trying to separate the ui and the implementation files. I used QT creator to create *.ui, then converted it to *.py main.py ``` from PyQt5 import QtCore, QtGui, QtWidgets from myUI import Ui_Form import sys class Prog(Ui_Form): def __init__(self): super().__init__(); def main(): Program = QtWidgets.QApplication(sys.argv); MyProg=Prog(); MyProg.show(); Program.exec_(); if __name__=='__main__': main(); ``` myUI.py ``` from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(QtWidgets.QWidget): def __init__(self): super().__init__(); self.setupUi(); def setupUi(self, Form): Form.setObjectName("Form") Form.resize(400, 300) self.pushButton = QtWidgets.QPushButton(Form) self.pushButton.setGeometry(QtCore.QRect(30, 230, 93, 28)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(Form) self.pushButton_2.setGeometry(QtCore.QRect(210, 250, 93, 28)) self.pushButton_2.setObjectName("pushButton_2") self.textEdit = QtWidgets.QTextEdit(Form) self.textEdit.setGeometry(QtCore.QRect(120, 80, 104, 87)) self.textEdit.setObjectName("textEdit") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.pushButton.setText(_translate("Form", "PushButton")) self.pushButton_2.setText(_translate("Form", "PushButton")) ``` My Questions are I got the error msg as follows. self.setupUi(); TypeError: setupUi() missing 1 required positional argument: 'Form' But if i change self.setupUi(); into self.setupUi(self); in myUI.py it works. I am wondering why self has to be invoked in self.setui() In myUI.py, Why there is def setupUi(self, Form):, not def setupUi(self): I know that is because we treated Form as a variable, and will use it later on. But, why we need it? or can we create a member as self.Form instead of invoking Form THX!

Original source