繁体   English   中英

PyQt5自我参考

[英]PyQt5 self reference

我使用Qt Designer来设计GUI,并使用PyQt5中的命令将.ui文件转换为.py。 由此,我想在单击按钮时输出一个消息框。 我已经在按钮侦听器的功能上使用此行代码成功完成了此操作:

QtWidgets.QMessageBox.about(MainWindow, "Result", "Invalid number entered!")

我已经在互联网上进行搜索,但是我不明白为什么这一项不起作用。

QtWidgets.QMessageBox.about(self, "Result", "Invalid number entered!")

他们自己也引用MainWindow吗?

这是完整的源代码。

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setWindowModality(QtCore.Qt.WindowModal)
        #MainWindow.resize(310, 185)
        MainWindow.setFixedSize(310, 185)
        MainWindow.setStyleSheet("#MainWindow\n"
    "{\n"
    "    background-color:qradialgradient(spread:pad, cx:0.5, cy:0.5, 
    radius:1.696, fx:0.5, fy:0.505682, stop:0 rgba(0, 85, 255, 255), stop:1 
    rgba(255, 255, 255, 255))\n"
    "}\n"
    "\n"
    "#firstNo_lineedit, #secondNo_lineedit\n"
    "{\n"
    "    \n"
    "    background-color: rgb(28, 255, 123);\n"
    "}\n"
    "\n"
    "")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.firstNo_lineedit = QtWidgets.QLineEdit(self.centralwidget)
        self.firstNo_lineedit.setGeometry(QtCore.QRect(130, 40, 113, 20))
        self.firstNo_lineedit.setObjectName("firstNo_lineedit")
        self.secondNo_lineedit = QtWidgets.QLineEdit(self.centralwidget)
        self.secondNo_lineedit.setGeometry(QtCore.QRect(130, 70, 113, 20))
        self.secondNo_lineedit.setObjectName("secondNo_lineedit")
        self.calculate_button = QtWidgets.QPushButton(self.centralwidget)
        self.calculate_button.setGeometry(QtCore.QRect(170, 100, 75, 23))
        self.calculate_button.setObjectName("calculate_button")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(60, 40, 81, 20))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(60, 70, 61, 20))
        self.label_2.setObjectName("label_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 310, 21))
        self.menubar.setObjectName("menubar")
        self.menuAbout = QtWidgets.QMenu(self.menubar)
        self.menuAbout.setObjectName("menuAbout")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuAbout.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # ================= Listeners ===================
        self.calculate_button.clicked.connect(self.basicArithmetic)
        # ============================================

    # ================= Events ===================
    def basicArithmetic(self):
        try:
            firstNo=float(self.firstNo_lineedit.text())
            secondNo=float(self.secondNo_lineedit.text())

            resSum=firstNo+secondNo
            resDiff=firstNo-secondNo
            resMul=firstNo*secondNo
            resDiv=round(firstNo/secondNo,2)

            print("Sum: {}".format(resSum))
            print("Difference: {}".format(resDiff))
            print("Product: {}".format(resMul))
            print("Quotient: {}".format(resDiv))

            toDisplay="Sum: {}".format(resSum)
            toDisplay+="\n"
            toDisplay+="Difference: {}".format(resDiff)
            toDisplay+="\n"
            toDisplay+="Product: {}".format(resMul)
            toDisplay+="\n"
            toDisplay+="Quotient: {}".format(resDiv)

            #QtWidgets.QMessageBox.about(self, "Result", toDisplay)
            QtWidgets.QMessageBox.about(MainWindow, "Result", toDisplay)

        except ValueError:
            #QtWidgets.QMessageBox.about(self, "Result", toDisplay)
            QtWidgets.QMessageBox.about(MainWindow, "Result", "Invalid number entered!")
    # ============================================

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.calculate_button.setText(_translate("MainWindow", "Calculate"))
        self.label.setText(_translate("MainWindow", "First No.:"))
        self.label_2.setText(_translate("MainWindow", "Second No.:"))
        self.menuAbout.setTitle(_translate("MainWindow", "About"))
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

self是引用相同实例的类的方法的第一个参数(名称是按惯例,不是必需的)。

对于另一个QMessageBox.about()需要一个继承自QWidget或None的某种对象作为第一个参数。

如果我们查看由Qt Designer生成的类,我们会清楚地看到它不是小部件,实际上,该类的唯一目的是成为填充其他小部件的接口:

MainWindow = QtWidgets.QMainWindow() # create widget
ui = Ui_MainWindow() # create interface
ui.setupUi(MainWindow) # fill widget

因此,要传递的self ,即Ui_MainWindow的实例是Ui_MainWindow ,因为它不引用窗口小部件,但是MainWindow是窗口小部件,因此它可以正确地使用此更改。 此外,在生成的文件中,您还会显示以下消息:

# WARNING! All changes made in this file will be lost!

该消息是因为,如果您要更改设计,则必须覆盖您编写的逻辑,例如basicArithmetic方法,这会使项目无法使用。

PyQt我建议创建另一个使用生成QtDesigner的类的类,我假设生成的文件名为design.py

design.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'design.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setWindowModality(QtCore.Qt.WindowModal)
        #MainWindow.resize(310, 185)
        MainWindow.setFixedSize(310, 185)
        MainWindow.setStyleSheet("#MainWindow\n"
    "{\n"
    "    background-color:qradialgradient(spread:pad, cx:0.5, cy:0.5," 
    "radius:1.696, fx:0.5, fy:0.505682, stop:0 rgba(0, 85, 255, 255), stop:1" 
    "rgba(255, 255, 255, 255))\n"
    "}\n"
    "\n"
    "#firstNo_lineedit, #secondNo_lineedit\n"
    "{\n"
    "    \n"
    "    background-color: rgb(28, 255, 123);\n"
    "}\n"
    "\n"
    "")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.firstNo_lineedit = QtWidgets.QLineEdit(self.centralwidget)
        self.firstNo_lineedit.setGeometry(QtCore.QRect(130, 40, 113, 20))
        self.firstNo_lineedit.setObjectName("firstNo_lineedit")
        self.secondNo_lineedit = QtWidgets.QLineEdit(self.centralwidget)
        self.secondNo_lineedit.setGeometry(QtCore.QRect(130, 70, 113, 20))
        self.secondNo_lineedit.setObjectName("secondNo_lineedit")
        self.calculate_button = QtWidgets.QPushButton(self.centralwidget)
        self.calculate_button.setGeometry(QtCore.QRect(170, 100, 75, 23))
        self.calculate_button.setObjectName("calculate_button")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(60, 40, 81, 20))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(60, 70, 61, 20))
        self.label_2.setObjectName("label_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 310, 21))
        self.menubar.setObjectName("menubar")
        self.menuAbout = QtWidgets.QMenu(self.menubar)
        self.menuAbout.setObjectName("menuAbout")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuAbout.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.calculate_button.setText(_translate("MainWindow", "Calculate"))
        self.label.setText(_translate("MainWindow", "First No.:"))
        self.label_2.setText(_translate("MainWindow", "Second No.:"))
        self.menuAbout.setTitle(_translate("MainWindow", "About"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

该新类可以具有以下形式:

main.py:

from PyQt5 import QtCore, QtGui, QtWidgets

from design import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)  

        # ================= Listeners ===================
        self.calculate_button.clicked.connect(self.basicArithmetic)
        # ============================================

    # ================= Events ===================
    def basicArithmetic(self):
        try:
            firstNo=float(self.firstNo_lineedit.text())
            secondNo=float(self.secondNo_lineedit.text())

            resSum=firstNo+secondNo
            resDiff=firstNo-secondNo
            resMul=firstNo*secondNo
            resDiv=round(firstNo/secondNo,2)

            print("Sum: {}".format(resSum))
            print("Difference: {}".format(resDiff))
            print("Product: {}".format(resMul))
            print("Quotient: {}".format(resDiv))

            toDisplay="Sum: {}".format(resSum)
            toDisplay+="\n"
            toDisplay+="Difference: {}".format(resDiff)
            toDisplay+="\n"
            toDisplay+="Product: {}".format(resMul)
            toDisplay+="\n"
            toDisplay+="Quotient: {}".format(resDiv)

            #QtWidgets.QMessageBox.about(self, "Result", toDisplay)
            QtWidgets.QMessageBox.about(self, "Result", toDisplay)

        except ValueError:
            #QtWidgets.QMessageBox.about(self, "Result", toDisplay)
            QtWidgets.QMessageBox.about(self, "Result", "Invalid number entered!")

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

这就是为什么在很多情况下, self被视为第一个参数的原因。

您可以在以下链接中找到更多信息:

没有自引用指向MainWindow继承于QtWidgets.QMainWindow() Ui_MainWindow类,因此,当您说QtWidgets.QMessageBox.about(self, "Result", toDisplay) ,会将Ui_MainWindow视为不正确的父QWidget

这次调用QtWidgets.QMessageBox.about(MainWindow, "Result", toDisplay)时,您的代码将运行良好,因为MainWindow是有效的QWidgetQtWidgets.QMainWindow()

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM