Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to separate the ui and implementation in PyQT?

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

  1. 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()

  2. 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!

like image 286
Craig Yang Avatar asked Sep 15 '25 16:09

Craig Yang


1 Answers

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.

like image 62
101 Avatar answered Sep 17 '25 07:09

101