点击取消会把所有对话框都关闭,而不是返回到上一个对话框

编程语言 2026-07-08

我的PyQt5应用有一个数据录入功能,会要求用户连接数据库并输入要上传的信息。下面是我的代码的一个简化版本:

import pandas as pd
from PyQt5.QtWidgets import (QDialog, QDialogButtonBox, QApplication,
                             QVBoxLayout, QTableWidget, QTableWidgetItem,
                             QComboBox)
from PyQt5.QtCore import Qt, pyqtSlot
import sys

#%%
class EnvSelect(QDialog):
    def __init__(self, lnew, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Environment Select")
        self.resize(800, 600)
        self.lnew = lnew
        self.result = None

        layout = QVBoxLayout()
        self.cbe = QComboBox()
        self.cbe.addItems(["Production", "Development"])
        layout.addWidget(self.cbe)
        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        self.buttonBox = QDialogButtonBox(QBtn)
        self.buttonBox.accepted.connect(self.onokclick)
        self.buttonBox.rejected.connect(self.reject)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def onokclick(self):
        de = DataEntry(self.lnew)
        if de.exec():
            df = de.result
            if df:
                print("Success")
            else:
                return # I assume the issue is here, but I don't know how else to quit the function without triggering self.accept()
        self.accept()

#%%
class DataEntry(QDialog):
    def __init__(self, lnew, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Data Entry")
        self.resize(800, 600)
        self.result = None
        self.df = pd.DataFrame(data=lnew, columns=["NAME"])
        self.df.insert(1, "ADDRESS", None)
        self.df.insert(2, "PHONE", None)

        layout = QVBoxLayout()
        self.tbl = QTableWidget()
        layout.addWidget(self.tbl)
        self.tbl.setColumnCount(3)
        self.tbl.setRowCount(len(lnew))
        self.tbl.setHorizontalHeaderLabels(["NAME", "ADDRESS", "PHONE"])
        for i in range(len(lnew)):
            self.tbl.setItem(i, 0, QTableWidgetItem(lnew[i]))
            self.tbl.item(i, 0).setFlags(Qt.ItemIsSelectable)
            for icol in range(1, 3):
                self.tbl.setItem(i, icol, QTableWidgetItem(None))
        self.tbl.cellChanged.connect(self.oncellchange)
        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        self.buttonBox = QDialogButtonBox(QBtn)
        self.buttonBox.accepted.connect(self.onokclick)
        self.buttonBox.rejected.connect(self.reject)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    @pyqtSlot(int, int)
    def oncellchange(self, irow, icol):
        self.df.iloc[irow, icol] = self.tbl.item(irow, icol).text()

    def onokclick(self):
        self.result = self.df
        self.accept()

#%%
if __name__ == '__main__':
    lnew = ["John", "Paul", "George", "Ringo"]
    app = QApplication(sys.argv)
    ex = EnvSelect(lnew)
    ex.show()
    sys.exit(app.exec_())

如果我在第一个对话框中点击Ok,然后在第二个对话框中点击Cancel,我希望第一个对话框保持打开,这样用户就可以修改他们的选择并再次点击Ok。但结果这两个对话框都被关闭了。我该如何实现我想要的行为?

解决方案

基于评论中的建议,我已经让代码跑通。以下是我所做的修改(并附上一些额外的注释,以便更好地说明上下文):

class EnvSelect(QDialog):
    def onokclick(self):
        # Skipped code that queries database for ADDRESS and PHONE of given NAMEs
        # df1 = pd.read_sql()
        # df2 = subset of df1 where both ADDRESS and PHONE are NULL
        ladd = df2["NAME"].to_list()
        if len(ladd):
            de = DataEntry(ladd)
            if de.exec() == QDialog.Accepted:
                df3 = de.result
                # Skipped code that adds df3 info back into df1
            else:
                return
        self.result = df1
        self.accept()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章