【问题标题】:how to separate the ui and implementation in PyQT?如何在 PyQT 中分离 ui 和 implementation?
【发布时间】:2015-01-28 11:49:00
【问题描述】:

我在尝试分离 ui 和实现文件时有一个问题。 我使用 QT creator 创建 *.ui,然后将其转换为 *.py

ma​​in.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(); 类型错误:setupUi() 缺少 1 个必需的位置参数:'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

谢谢!

【问题讨论】:

  • 转换后的ui文件使用方法请见pyuic5 documentation
  • 所以更好的办法是声明一个 ui 类成员?但在文档中,它还提供了继承自 UI 类的示例。

标签: python user-interface inheritance pyqt pyside


【解决方案1】:

更改 UI 文件不是一个好主意,因为每次您在 Qt Creator 中更新 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 在 QT 中是不是有点保守?
猜你喜欢
  • 2017-04-17
  • 1970-01-01
  • 2021-07-10
  • 2020-09-07
  • 1970-01-01
  • 2016-02-06
  • 2012-11-13
  • 1970-01-01
相关资源
最近更新 更多