如何在PyQT中分离UI和实现?

3

在尝试分离UI和实现文件时,我有一个问题。我使用QT Creator创建了*.ui文件,然后将其转换为*.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"))

我的问题如下:

  1. 我收到了以下错误消息。

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

    但是,如果在myUI.py中将self.setupUi();更改为self.setupUi(self);,它就可以工作了。我想知道为什么要在self.setui()中调用self

  2. 在myUI.py中,为什么有def setupUi(self, Form):,而不是def setupUi(self):

    我知道这是因为我们将Form视为变量,并且稍后会使用它。但是,为什么我们需要它?或者我们是否可以创建一个成员self.Form来代替调用Form

谢谢!


3
请参考pyuic5文档了解如何使用转换后的UI文件。 - ekhumoro
那么更好的想法是声明一个UI类成员吗?但是在文档中,它也提供了从UI类继承的示例。 - Craig Yang
1个回答

4

修改UI文件并不是一个好主意,因为每次在Qt Creator中更新UI时都会重新生成UI文件,并且所有的更改都会丢失。

相反,建议创建另一个UI类来调用自动生成的文件(正如ekhumoro指出的,还有其他定义UI类的设计):

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_())

通过这种方式,类Prog的一个实例被传递到setupUi方法中(selfProg实例对自身的引用)。在setupUi方法中,这个引用被称为Form,并且在您的代码中被多次使用,如下所示:

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

Form 可能因为在 Qt Creator 中将 objectName 设置为 Form 才得名。但是,无论它叫什么名称,它都是自动生成文件需要设置的父部件的引用。如果你将它们命名为相同的名称,例如将 Prog 类和 UI 的 objectName 重命名为类似 ProgramUI 的名称,则在概念上更有意义。


你部分回答了我的问题。但是为什么我们需要在这里使用“Form”呢?对于变量来说,除非我们声明它,否则我们无法使用它。看起来“Form”似乎没有任何理由(没有声明),但我们需要它。在QT中,“Form”是一种保守的词汇吗? - Craig Yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接