请查看我的应用程序中的以下代码片段:
requestDialogSignal = QtCore.pyqtSignal()
class MainWindow(QMainWindow):
def __init__(self):
...
self.requestDialogSignal.connect(self.slotRequestDialog, Qt.QueuedConnection)
def slotRequestDialog():
mbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.NoIcon, "title", "message")
mbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
result = mbox.exec()
def CreateDialogs(self):
self.requestDialogSignal.emit()
time.sleep(1)
self.requestDialogSignal.emit()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
t = threading.Thread(target=window.CreateDialogs)
t.start()
app.exec()
本质上,我试图实现的是第二个QMessageBox
只有在第一个得到回答后才会出现。我期望第一个QMessageBox
阻塞exec()
上的接收器线程,这是因为Qt.QueuedConnection
不允许第二次调用该插槽。如果我将连接更改为Qt.BlockingQueuedConnection
,它会按预期运行,尽管这会阻塞发送线程,这不是我想要的。
发布于 2021-11-09 10:59:24
试试这样的东西。我没有测试它,因为我的机器上既没有PyQt也没有PySide。可能会有一些小问题,但逻辑是清晰的,我希望可以理解。
requestDialogSignal = QtCore.pyqtSignal()
class MainWindow(QMainWindow):
def __init__(self):
self.state = 0 # a state variable which can be used to define the dialog opening logic
...
def openDialog(self):
mbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.NoIcon, "title", "message", self) # use self to give the dialog a parent; not strictly needed but it is a good practice
mbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
mbox.finished.connect(self.onDialogFinished) # or you can connect to accepted or rejected signals to finetune the logic
mbox.open() # open() makes the dialog window-modal but does not block the code
def onDialogFinished(self):
self.state += 1
if self.state == 1: # makes sure we open te dialog only twice, but you can change the logic as you like with the state variable
self.openDialog()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
window.openDialog()
app.exec()
我相信下面的解决方案也应该是可行的,但它是丑陋的,原因有三。1)在应用程序的exec()
之前调用对话框的exec()
。2)使用过多的exec()
,这不是一个好的做法。如果可能的话,应该避免使用exec()
。3)包含不必要的递归...我认为这三种反对意见没有一个是错的,它们只是丑陋,我不喜欢它们。
requestDialogSignal = QtCore.pyqtSignal()
class MainWindow(QMainWindow):
def __init__(self):
self.state = 0 # a state variable which can be used to define the dialog opening logic
...
def execDialog(self):
mbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.NoIcon, "title", "message", self)
mbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
mbox.exec() # blocks the code until closed
self.state += 1
if self.state == 1: # makes sure we open te dialog only twice, but you can change the logic as you like with the state variable
self.execDialog()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
window.execDialog()
app.exec()
我觉得你的代码奇怪的是,你把同一个对话框显示了两次。这真的是你想要的吗?我猜你实际上想要显示两个不同的对话框。在这种情况下,代码看起来会不同。但不管怎样,我已经向您展示了如何避免线程以及如何正确使用(或避免) exec()
。我非常赞成使用我的第一个例子,而不是第二个。
https://stackoverflow.com/questions/69894885
复制相似问题