How to separate ui and implementation in PyQT?

I have a question while I am trying to separate ui files and implementations. I used the QT creator to create * .ui and 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

  • I got the msg error as follows.

    self.setupUi (); TypeError: setupUi () missing 1 required positional argument: 'Form'

    But if I change self.setupUi (); on self.setupUi (self); in myUI.py

    it works. I am wondering why self needs to be called in self.setui ()

  • In myUI.py, why is there def setupUi (self, Form): and not def setupUi (self):

    I know this is because we treated the form as a variable and will use it later. But why do we need this? or we can create the element as self.Form instead of calling Form

thank!

+3


source to share


1 answer


It is not a good idea to change the UI file as it will be updated every time the user interface is updated in Qt Creator and any changes will be lost.

Instead, create another UI class that calls the auto-generated file for you (and there are other constructs to define the UI class, as ehumoro 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_())

      



So the instance of the class Prog

is passed to the method setupUi

( self

is the reference the instance has Prog

). In the method, setupUi

this link is called Form

and used many times, as you can see in your code:

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

      

Form

so named probably because you have set objectName

in Form

in Qt Creator. However, no matter what it is called, it is a link to the parent widget that the auto-generated file should be configured with. Conceptually it would make more sense if you called them the same, for example. rename both classes Prog

and UI objectName

to something like ProgramUI

.

+4


source







All Articles