如何覆盖 QDialog.accept()?

Posted

技术标签:

【中文标题】如何覆盖 QDialog.accept()?【英文标题】:How to overwrite QDialog.accept()? 【发布时间】:2020-04-20 06:22:55 【问题描述】:

我有一个主窗口,它在按下按钮时打开一个对话框。我想覆盖对话框的接受功能,这样我就可以实现一些在接受对话框之前应该执行的自定义功能。这是我的主窗口的示例代码。

from PySide2 import QtCore, QtGui, QtWidgets
from add_new import Add_new_dialog
import sys

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(500, 100)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushNew_Bed = QtWidgets.QPushButton(self.centralwidget)
        self.pushNew_Bed.setObjectName("pushNew_Bed")
        self.pushNew_Bed.resize(QtCore.QSize(500,100))
        self.pushNew_Bed.clicked.connect(self.on_add_new_clicked)



    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushNew_Bed.setText(_translate("MainWindow", "Add New Bed"))



    def on_add_new_clicked(self):
        Dialog = QtWidgets.QDialog()
        Dialog.ui = Add_new_dialog()
        Dialog.ui.setupUi(Dialog)
        #dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        retValue = Dialog.exec_()
        if retValue == 1:
            print("Accepted")#dialog.calendarWidget.selectedDate())



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

这是对话框。

from PySide2 import QtCore, QtGui, QtWidgets
import sys

class Add_new_dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        Dialog.setMinimumSize(QtCore.QSize(400, 300))
        Dialog.setMaximumSize(QtCore.QSize(400, 300))

        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")


        self.retranslateUi(Dialog)
        #self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.accepted.connect(self.custom_func)
        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)


    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))


    def custom_func(self):
        Dialog.accept()
        print("custom func")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Add_new_dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

如果我独立启动对话框,一切都会按预期工作。但是,如果我从主窗口调用它,可以预见的是,我会得到一个错误。

    Dialog.accept()
NameError: name 'Dialog' is not defined

我已尝试将以下代码添加到对话框以覆盖接受功能:

def accept(self):
    self.custom_func()
    Dialog.done(QtWidgets.QDialog.Accepted)

并将按钮绑定到该功能

self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(Dialog.reject)

同样,可以预见的是,我得到了相同的结果。阅读文档并没有太大帮助。非常感谢任何帮助,我为这个愚蠢的问题道歉,但我是一个完整的 gui 初学者。提前谢谢你。

【问题讨论】:

【参考方案1】:

你不应该修改 Qt Designer 生成的类,所以你必须重新生成 .py(更多信息阅读here)所以我假设类Ui_MainWindowAdd_new_dialog属于文件@987654324 @ 和 add_new_dialog_ui.py,分别。

考虑到上述情况,你应该重写继承QDialog的类的方法:

ma​​in.py

from PySide2 import QtCore, QtGui, QtWidgets

from mainwindow_ui import Ui_MainWindow
from add_new_dialog_ui import Add_new_dialog


class AddDialog(QtWidgets.QDialog, Add_new_dialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

    def accept(self):
        print("custom func")
        super().accept()


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.pushNew_Bed.clicked.connect(self.on_add_new_clicked)

    def on_add_new_clicked(self):
        dialog = AddDialog()
        retValue = dialog.exec_()
        if retValue == QtWidgets.QDialog.Accepted:
            print("Accepted")


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

【讨论】:

效果很好,谢谢!另外感谢您向我展示了在不更改生成代码的情况下处理我的窗口的方法。接受并赞成。

以上是关于如何覆盖 QDialog.accept()?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Rails 中的 gem 覆盖类的方法?

如何在JavaScript中预先添加/附加所有函数调用的结果

本田带低速前车跟随(LSF)的主动巡航控制(ACC)图标亮了代表啥意思

如何理解 Keras 模型拟合中的 loss acc val_loss val_acc

我们如何从 ACCE 调试批量操作 javascript?

如何将 json 文件转换为 python 类?