如何重新实现 QDialog 的接受和拒绝槽?

How to reimplement a QDialog's accept and reject slots?

我正在开发一个 GUI 项目,其中用户面临以下 QDialog:

class StockSelectorDialog(QDialog, stockselector_ui):
    def __init__(self, parent_, *args, **kwargs):
        super(StockSelectorDialog, self).__init__(*args, **kwargs)
        self.setAttribute(Qt.WA_DeleteOnClose, on=True)

        self.setupUi(self)
        self.dialogButtonBox.accepted.connect(self.accept)
        self.dialogButtonBox.rejected.connect(self.reject)

        self.parent_ = parent_
        self.symbolsbuffer = parent_.symbols.copy()

        self.symbolmodel = SymbolListModel(self)
        self.listView.setModel(self.symbolmodel)

        self.symbolAddButton.clicked.connect(self.onAddButtonClicked)
        self.symbolDeleteButton.clicked.connect(self.onDeleteButtonClicked)

    def onAddButtonClicked(self, s):
        symbol = self.symbolEdit.text()
        if symbol:
            self.symbolsbuffer.append(symbol)
            self.symbolmodel.layoutChanged.emit()
            self.symbolEdit.setText("")

    def onDeleteButtonClicked(self, s):
        indexes = self.listView.selectedIndexes()
        if indexes:
            for i in indexes:
                del self.symbolsbuffer[i.row()]

            self.symbolmodel.layoutChanged.emit()
            self.listView.clearSelection()

    def accept(self):
        self.parent_.symbols = self.symbolsbuffer
        self.parent_.onSymbolsChanged()
        self.close()

    def reject(self):
        self.close()

UI 文件在这里:https://github.com/danib-prog/stockmarket-helper/blob/master/stockselector.ui

一切正常,直到我添加了缓冲区系统,为此我不得不重新实现对话框的 acceptreject 插槽(尽管我对后者不太确定) .现在,对话框会在必要时打开,ListView 可以正常使用所有按钮和 LineEdit,但我的 dialogButtonBox 没有响应。

为什么会这样?问题的解决方案是什么?

您不应该为此在对话框中调用 close(),主要是因为它会导致调用 reject();幸运的是 Qt 足够聪明,可以防止递归,但重点仍然存在:这两种方法都应该设置对话框的 result 并使用 done(),of close(),所以他们的事件循环正确地退出了 exec_().

如果您需要重写 class 函数来执行默认行为 以外的操作 ,您应该始终记住也要调用基础实现以便正确达到预期效果。

    def accept(self):
        self.parent_.symbols = self.symbolsbuffer
        self.parent_.onSymbolsChanged()
        super(StockSelectorDialog, self).accept()

    def reject(self):
        super(StockSelectorDialog, self).reject()

此外,请注意 Qt Designer 在使用带按钮的默认对话框模板创建时已经连接了 QDialogBu​​ttonBox 的按钮,因此您不应该再次连接它们,否则 acceptreject会被调用两次。