在子类对话框窗口中使用方法影响主窗口的问题

时间:2019-05-27 00:25:48

标签: python pyqt pyqt5 qt-designer qdialog

我正在尝试使用PyQT5创建一个GUI程序。我是编程和Python的新手,所以如果我用错误的方式解释事情,请纠正我。

我有一个主窗口,其中包含多个QLineEdit小部件和相应的“清除”按钮,以清除用户输入的数据。主窗口还包含“编辑”按钮,以显示特定对话框,在该对话框中还可以编辑数据。我的示例具有“用户ID” QLineEdit小部件/文本框,“清除”和“编辑”按钮。

单击“编辑”时出现的对话框具有其自己的“清除”按钮。如果单击对话框窗口中的“清除”按钮,则应清除对话框和主窗口中的QLineEdit小部件。

问题::当我从对话框类继承主窗口类时,用于清除用户ID字段的方法clearUserID()失败。

当我不从主窗口类继承时,clearUserID方法起作用,并且我可以清除对话框QLineEdit(UserIDWin_UserID_lnedt),但不能清除主窗口上相应的窗口小部件(UserID_lnedt)。我尝试使用对话框“清除”按钮清除主窗口QLineEdit小部件的所有代码都导致我的程序崩溃。

请有人帮我更好地理解这些原理背后的逻辑以及如何使我的代码正常工作吗?谢谢。

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(820, 611)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 801, 551))
        self.tabWidget.setObjectName("tabWidget")
        self.MainTab = QtWidgets.QWidget()
        self.MainTab.setObjectName("MainTab")
        self.UserID_Edit_pb = QtWidgets.QPushButton(self.MainTab)
        self.UserID_Edit_pb.setGeometry(QtCore.QRect(210, 10, 31, 23))
        self.UserID_Edit_pb.setObjectName("UserID_Edit_pb")
        self.UserID_Edit_pb.clicked.connect(self.openUserIDWin)
        self.UserID_Clear_pb_2 = QtWidgets.QPushButton(self.MainTab)
        self.UserID_Clear_pb_2.setGeometry(QtCore.QRect(170, 9, 41, 23))
        self.UserID_Clear_pb_2.setObjectName("UserID_Clear_pb_2")
        self.UserID_le = QtWidgets.QLineEdit(self.MainTab)
        self.label = QtWidgets.QLabel(self.MainTab)
        self.label.setGeometry(QtCore.QRect(10, 10, 47, 13))
        self.UserID_le.setGeometry(QtCore.QRect(50, 10, 113, 20))
        self.UserID_le.setObjectName("UserID_le")
        self.tabWidget.addTab(self.MainTab, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 820, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.UserID_Clear_pb_2.clicked.connect(self.UserID_le.clear)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.UserID_Edit_pb.setText(_translate("MainWindow", "Edit"))
        self.UserID_Clear_pb_2.setText(_translate("MainWindow", "Clear"))
        self.label.setText(_translate("MainWindow", "User ID"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.MainTab), _translate("MainWindow", "Tab"))

    def openUserIDWin(self):
        UserID_value = self.UserID_le.text()
        UserIDWin = QtWidgets.QDialog()
        ui = Ui_UserIDWin(UserID_value)
        ui.setupUi(UserIDWin)
        UserIDWin.exec_();



class Ui_UserIDWin(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, userID):
        print("The User ID is:" + userID)
        self.userID = userID

    def setupUi(self, UserIDWin):
        UserIDWin.setObjectName("UserIDWin")
        UserIDWin.resize(400, 124)
        self.UserIDWin_UserID_lnedt = QtWidgets.QLineEdit(UserIDWin)
        self.UserIDWin_UserID_lnedt.setText(self.userID)
        self.UserIDWin_UserID_lnedt.setGeometry(QtCore.QRect(20, 50, 113, 20))
        self.UserIDWin_UserID_lnedt.setObjectName("UserIDWin_UserID_lnedt")
        self.UserIDWin_UserID_lbl = QtWidgets.QLabel(UserIDWin)
        self.UserIDWin_UserID_lbl.setGeometry(QtCore.QRect(20, 30, 47, 13))
        self.UserIDWin_UserID_lbl.setObjectName("UserIDWin_UserID_lbl")
        self.UserIDWin_UserIDClear_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_UserIDClear_pushb.setGeometry(QtCore.QRect(140, 50, 41, 23))
        self.UserIDWin_UserIDClear_pushb.setObjectName("UserIDWin_UserIDClear_pushb")
        self.UserIDWin_Cancel_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_Cancel_pushb.setGeometry(QtCore.QRect(110, 80, 75, 23))
        self.UserIDWin_Cancel_pushb.setObjectName("UserIDWin_Cancel_pushb")
        self.UserIDWin_Next_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_Next_pushb.setGeometry(QtCore.QRect(190, 80, 75, 23))
        self.UserIDWin_Next_pushb.setObjectName("UserIDWin_Next_pushb")

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

        #If I do not inherit from "QtWidgets.QMainWindow, Ui_MainWindow" the code below works and invokes clearUserId().  However, I then am having problems using SetText on the main window UserId_le text box and the program crashes.
        self.UserIDWin_UserIDClear_pushb.clicked.connect(self.clearUserID)

    def retranslateUi(self, UserIDWin):
        _translate = QtCore.QCoreApplication.translate
        UserIDWin.setWindowTitle(_translate("UserIDWin", "Dialog"))
        self.UserIDWin_UserID_lbl.setText(_translate("UserIDWin", "User ID"))
        self.UserIDWin_UserIDClear_pushb.setText(_translate("UserIDWin", "Clear"))
        self.UserIDWin_Cancel_pushb.setText(_translate("UserIDWin", "Cancel"))
        self.UserIDWin_Next_pushb.setText(_translate("UserIDWin", "Next"))

    def clearUserID(self):
        self.UserIDWin_UserID_lnedt.setText('')
        # The line below crashes my program if I am able to invoke this method.
        #self.Ui_MainWindow.UserID_le.setText('')

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

1 个答案:

答案 0 :(得分:1)

似乎他们对继承和良好实践有某些明确的概念,但其他人则不喜欢以下内容:

  • PyQt建议不要修改Qt Designer生成的代码,因为您将来可能要修改GUI,并且在使用pyuic时,初始代码将被覆盖。另一个问题是,初学者不了解Qt Designer生成的类不是窗口小部件,而是用于填充另一个窗口小部件的接口,因此除其他问题外,无法覆盖窗口小部件的方法。

    < / li>
  • 仅当两个类具有相同的作用域时,才需要从另一个类的对象中修改一个类的对象,这种情况下,要从另一个窗口中清除主窗口的QLineEdit是一个危险的任务,相反,您应该在两个窗口具有相同范围且位于openUserIDWin方法中的情况下执行该逻辑。

  • QLineEdit已经具有允许清除的clear()方法,它实现的功能与setText(“”)相同,但第一种方法更具可读性。

考虑到上述情况,解决方案是:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(820, 611)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 801, 551))
        self.tabWidget.setObjectName("tabWidget")
        self.MainTab = QtWidgets.QWidget()
        self.MainTab.setObjectName("MainTab")
        self.UserID_Edit_pb = QtWidgets.QPushButton(self.MainTab)
        self.UserID_Edit_pb.setGeometry(QtCore.QRect(210, 10, 31, 23))
        self.UserID_Edit_pb.setObjectName("UserID_Edit_pb")
        self.UserID_Clear_pb_2 = QtWidgets.QPushButton(self.MainTab)
        self.UserID_Clear_pb_2.setGeometry(QtCore.QRect(170, 9, 41, 23))
        self.UserID_Clear_pb_2.setObjectName("UserID_Clear_pb_2")
        self.UserID_le = QtWidgets.QLineEdit(self.MainTab)
        self.label = QtWidgets.QLabel(self.MainTab)
        self.label.setGeometry(QtCore.QRect(10, 10, 47, 13))
        self.UserID_le.setGeometry(QtCore.QRect(50, 10, 113, 20))
        self.UserID_le.setObjectName("UserID_le")
        self.tabWidget.addTab(self.MainTab, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 820, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.UserID_Edit_pb.setText(_translate("MainWindow", "Edit"))
        self.UserID_Clear_pb_2.setText(_translate("MainWindow", "Clear"))
        self.label.setText(_translate("MainWindow", "User ID"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.MainTab), _translate("MainWindow", "Tab"))


class Ui_UserIDWin(object):
    def setupUi(self, UserIDWin):
        UserIDWin.setObjectName("UserIDWin")
        UserIDWin.resize(400, 124)
        self.UserIDWin_UserID_lnedt = QtWidgets.QLineEdit(UserIDWin)
        self.UserIDWin_UserID_lnedt.setGeometry(QtCore.QRect(20, 50, 113, 20))
        self.UserIDWin_UserID_lnedt.setObjectName("UserIDWin_UserID_lnedt")
        self.UserIDWin_UserID_lbl = QtWidgets.QLabel(UserIDWin)
        self.UserIDWin_UserID_lbl.setGeometry(QtCore.QRect(20, 30, 47, 13))
        self.UserIDWin_UserID_lbl.setObjectName("UserIDWin_UserID_lbl")
        self.UserIDWin_UserIDClear_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_UserIDClear_pushb.setGeometry(QtCore.QRect(140, 50, 41, 23))
        self.UserIDWin_UserIDClear_pushb.setObjectName("UserIDWin_UserIDClear_pushb")
        self.UserIDWin_Cancel_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_Cancel_pushb.setGeometry(QtCore.QRect(110, 80, 75, 23))
        self.UserIDWin_Cancel_pushb.setObjectName("UserIDWin_Cancel_pushb")
        self.UserIDWin_Next_pushb = QtWidgets.QPushButton(UserIDWin)
        self.UserIDWin_Next_pushb.setGeometry(QtCore.QRect(190, 80, 75, 23))
        self.UserIDWin_Next_pushb.setObjectName("UserIDWin_Next_pushb")

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

    def retranslateUi(self, UserIDWin):
        _translate = QtCore.QCoreApplication.translate
        UserIDWin.setWindowTitle(_translate("UserIDWin", "Dialog"))
        self.UserIDWin_UserID_lbl.setText(_translate("UserIDWin", "User ID"))
        self.UserIDWin_UserIDClear_pushb.setText(_translate("UserIDWin", "Clear"))
        self.UserIDWin_Cancel_pushb.setText(_translate("UserIDWin", "Cancel"))
        self.UserIDWin_Next_pushb.setText(_translate("UserIDWin", "Next"))


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.UserID_Edit_pb.clicked.connect(self.openUserIDWin)
        self.UserID_Clear_pb_2.clicked.connect(self.UserID_le.clear)

    def openUserIDWin(self):
        UserID_value = self.UserID_le.text()
        w = UserIDWin(UserID_value)
        w.UserIDWin_UserIDClear_pushb.clicked.connect(self.UserID_le.clear)
        w.exec_()


class UserIDWin(QtWidgets.QDialog, Ui_UserIDWin):
    def __init__(self, userID, parent=None):
        super(UserIDWin, self).__init__(parent)
        self.setupUi(self)
        self.userID = userID
        self.UserIDWin_UserID_lnedt.setText(self.userID)
        self.UserIDWin_UserIDClear_pushb.clicked.connect(self.UserIDWin_UserID_lnedt.clear)


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

我建议您阅读: