调用QDialog.reject()无效果?如何在指定条件下关闭对话框?
问题原因
你在MyDialog的__init__方法中调用self.reject()时,对话框还未进入exec()启动的事件循环。exec()方法会在调用时初始化对话框状态并启动事件循环,之前调用的reject()不会被事件循环处理,所以对话框依然会正常显示,直到你手动触发accept()。
解决方案
有几种方式可以实现你的预期:
方法一:使用QTimer延迟调用reject
把self.reject()替换为QTimer.singleShot(0, self.reject),将reject()操作加入事件队列,等exec()启动事件循环后立即执行:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QVBoxLayout from PySide6.QtCore import QTimer # 导入QTimer class MyDialog(QDialog): def __init__(self): super().__init__() print('MyDialog created') self.setWindowTitle('My Dialog') button = QPushButton('Close') button.clicked.connect(self.accept) self.setLayout(QVBoxLayout()) self.layout().addWidget(button) QTimer.singleShot(0, self.reject) # 延迟调用reject class MainWindow(QMainWindow): def __init__(self): super().__init__() button = QPushButton("Press Me!") button.clicked.connect(self.show_dialog) self.setCentralWidget(button) def show_dialog(self): d = MyDialog() rv = d.exec() if rv == QDialog.Accepted: print('Dialog accepted') else: print('Dialog rejected') app = QApplication([]) window = MainWindow() window.show() app.exec()
方法二:在showEvent中调用reject
重写showEvent方法,在对话框即将显示时调用reject():
class MyDialog(QDialog): def __init__(self): super().__init__() print('MyDialog created') self.setWindowTitle('My Dialog') button = QPushButton('Close') button.clicked.connect(self.accept) self.setLayout(QVBoxLayout()) self.layout().addWidget(button) def showEvent(self, event): super().showEvent(event) self.reject()
方法三:直接设置结果并跳过显示
如果完全不想显示对话框,可以在创建后直接设置结果,无需启动exec()的事件循环:
def show_dialog(self): d = MyDialog() d.setResult(QDialog.Rejected) rv = d.result() if rv == QDialog.Accepted: print('Dialog accepted') else: print('Dialog rejected')
关键原理
QDialog的exec()方法会启动一个本地事件循环,只有在这个事件循环运行期间,调用accept()或reject()才会触发对话框关闭并返回对应结果。在__init__中调用reject()时,事件循环尚未启动,所以这个操作不会生效。
内容的提问来源于stack exchange,提问作者Troels Blum
相关产品推荐
相关产品推荐

