我无法完全关闭 PyQt5 脚本
I can't close completely PyQt5 script
当我 运行 以下名为 test2.py 的脚本时,如果我单击“确定”或“取消”按钮,window 将关闭但我没有收到提示。我想我忘记了一些愚蠢的事情......
这是 test2.py 脚本:
from PyQt5 import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
import sys
import unittest
class MainAppWindow(QMainWindow):
def __init__(self):
super().__init__()
dialog = Qt.QDialog()
buttonbox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel)
layout = Qt.QVBoxLayout()
param_box = Qt.QGroupBox('Iterate over parameters:')
pblayout = Qt.QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = Qt.QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = Qt.QGridLayout()
wid = Qt.QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
dialog.setLayout(layout)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(Qt.QLabel('iter. / database:'), 0, 0, 1, 3)
param_lay.addWidget(Qt.QLabel('iter.:'), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print('dialog not accepted')
else:
print('dialog accepted')
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainAppWindow()
sys.exit(app.exec_())
当我 运行 带有 python3 test2.py
的脚本时,我在标准输出中观察到 dialog accepted
或 dialog not accepted
,具体取决于单击的按钮,window 关闭但我没有得到提示。我必须手动停止 (CtrLZ) 才能得到提示。
问题是您有 2 个事件循环:dialog.exec_()
和 app.exec_()
所以当第一个事件循环完成时,另一个事件循环开始。另一方面,创建从 MainAppWindow 继承的 class 是没有用的,因为 window 从未使用或显示过。
一种可能的解决方案是只启动一个事件循环:
import sys
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QDialogButtonBox,
QGridLayout,
QGroupBox,
QLabel,
QMainWindow,
QScrollArea,
QVBoxLayout,
QWidget,
)
def main():
dialog = QDialog()
buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
layout = QVBoxLayout(dialog)
param_box = QGroupBox("Iterate over parameters:")
pblayout = QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = QGridLayout()
wid = QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(QLabel("iter. / database:"), 0, 0, 1, 3)
param_lay.addWidget(QLabel("iter.:"), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print("dialog not accepted")
else:
print("dialog accepted")
if __name__ == "__main__":
app = QApplication(sys.argv)
main()
当我 运行 以下名为 test2.py 的脚本时,如果我单击“确定”或“取消”按钮,window 将关闭但我没有收到提示。我想我忘记了一些愚蠢的事情......
这是 test2.py 脚本:
from PyQt5 import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
import sys
import unittest
class MainAppWindow(QMainWindow):
def __init__(self):
super().__init__()
dialog = Qt.QDialog()
buttonbox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel)
layout = Qt.QVBoxLayout()
param_box = Qt.QGroupBox('Iterate over parameters:')
pblayout = Qt.QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = Qt.QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = Qt.QGridLayout()
wid = Qt.QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
dialog.setLayout(layout)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(Qt.QLabel('iter. / database:'), 0, 0, 1, 3)
param_lay.addWidget(Qt.QLabel('iter.:'), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print('dialog not accepted')
else:
print('dialog accepted')
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainAppWindow()
sys.exit(app.exec_())
当我 运行 带有 python3 test2.py
的脚本时,我在标准输出中观察到 dialog accepted
或 dialog not accepted
,具体取决于单击的按钮,window 关闭但我没有得到提示。我必须手动停止 (CtrLZ) 才能得到提示。
问题是您有 2 个事件循环:dialog.exec_()
和 app.exec_()
所以当第一个事件循环完成时,另一个事件循环开始。另一方面,创建从 MainAppWindow 继承的 class 是没有用的,因为 window 从未使用或显示过。
一种可能的解决方案是只启动一个事件循环:
import sys
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QDialogButtonBox,
QGridLayout,
QGroupBox,
QLabel,
QMainWindow,
QScrollArea,
QVBoxLayout,
QWidget,
)
def main():
dialog = QDialog()
buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
layout = QVBoxLayout(dialog)
param_box = QGroupBox("Iterate over parameters:")
pblayout = QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = QGridLayout()
wid = QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(QLabel("iter. / database:"), 0, 0, 1, 3)
param_lay.addWidget(QLabel("iter.:"), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print("dialog not accepted")
else:
print("dialog accepted")
if __name__ == "__main__":
app = QApplication(sys.argv)
main()