Проблемы с использованием метода в диалоговом окне подкласса для воздействия на главное окно - PullRequest
1 голос
/ 27 мая 2019

Я пытаюсь создать программу с графическим интерфейсом, используя PyQT5.Я новичок в программировании и Python, поэтому, если я объясняю что-то неправильно, поправьте меня.

У меня есть главное окно, которое будет содержать несколько виджетов QLineEdit и соответствующие кнопки «Очистить», чтобы очистить пользователя.введенные данные.Главное окно также содержит кнопки «Редактировать» для отображения определенных диалоговых окон, в которых данные также можно редактировать.В моем примере есть виджет / текстовое поле QLineEdit «Идентификатор пользователя», кнопки «Очистить» и «Редактировать».

Диалоговое окно, которое появляется при нажатии «Редактировать», имеет собственную кнопку «Очистить».нажата кнопка «Очистить» в диалоговом окне, и виджет QLineEdit в диалоговом окне, и главное окно должны быть очищены.

Проблема: Когда я наследую класс главного окна от класса диалогаМетод 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 Ответ

1 голос
/ 27 мая 2019

Кажется, что у них есть определенные четкие понятия о наследовании и передовой практике, но другим не нравится следующее:

  • PyQt рекомендует не изменять код, сгенерированный Qt Designer, потому что вы, вероятно, захотите изменить графический интерфейс в будущем, и при использовании pyuic исходный код будет перезаписан. Другая проблема заключается в том, что новички не понимают, что класс, сгенерированный Qt Designer, является не виджетом, а интерфейсом, который служит для заполнения другого виджета, и, следовательно, не может перезаписывать методы виджетов в дополнение к другим проблемам.

  • Вам нужно только изменить объект класса из объекта другого класса, если оба имеют одинаковую область видимости, в вашем случае, когда вы хотите очистить 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_())

Рекомендую прочитать:

...