在 QtWidgets 的 PyQt5 中按下角落的红色 x 按钮时如何处理/覆盖?
Posted
技术标签:
【中文标题】在 QtWidgets 的 PyQt5 中按下角落的红色 x 按钮时如何处理/覆盖?【英文标题】:How to handle/override when the red x button in the corner is pressed in PyQt5 for QtWidget? 【发布时间】:2019-08-09 11:41:16 【问题描述】:我在 PyQt5 中创建了一个 gui,并且有几个窗口类由一个名为 Controller 的类控制。
背景: 在其中一个窗口(A)中,您可以按下按钮,然后会弹出一个新窗口(B),并且 A 被禁用。然后,当从窗口 B 按下退出按钮时,它会返回到窗口 A,而不在窗口 B 中保存编辑并启用窗口 A,如果在 B 中按下继续按钮,则重新打开窗口 A 并启用它。
问题: 但是,当按下窗口 B 角落的 x 按钮时,窗口关闭,窗口 A 被禁用。因此,我的问题是:当 B 关闭时,如何使窗口 A 再次启用? 我可以覆盖红角 x 事件,以便能够再次启用窗口 A 吗?
PS!我试图使代码最小化和可重复,如果有什么我应该修复的,请告诉我:)
import sys
from PyQt5 import QtCore, QtWidgets
class WindowTwo(QtWidgets.QWidget):
switch_window = QtCore.pyqtSignal()
def __init__(self, M, S):
QtWidgets.QWidget.__init__(self)
self.S = S
self.M = M
self.setupUi ( self )
self.setWindowTitle ( 'M' )
def setupUi(self, CM):
CM.setEnabled ( True )
CM.setFocusPolicy ( QtCore.Qt.TabFocus )
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QLabel("M: " ),0,0)
layout.addWidget(QtWidgets.QLabel("S: " ),0,1)
self.QuitButton = QtWidgets.QPushButton ( "Quit" )
self.QContinueButton = QtWidgets.QPushButton ( "Continue" )
self.QuitButton.clicked.connect ( CM.close )
self.QContinueButton.clicked.connect( lambda: self.windowtwo(self.M))
layout.addWidget( self.QuitButton, 10, 1 )
layout.addWidget ( self.QContinueButton, 10, 2 )
self.setLayout ( layout )
def windowtwo( self, M):
self.M = M
self.switch_window.emit()
class MS(QtWidgets.QWidget):
switch_window = QtCore.pyqtSignal(int)
def __init__(self, M, S):
QtWidgets.QWidget.__init__(self)
self.S = S
self.M = M
self.setupUi ( self )
self.setWindowTitle ( 'M' )
def setupUi(self, CM):
CM.setEnabled ( True )
CM.setFocusPolicy ( QtCore.Qt.TabFocus )
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QLabel("M: " ),0,0)
layout.addWidget(QtWidgets.QLabel("S: " ),0,1)
self.QWindowTwoButton = QtWidgets.QPushButton ( ' Go to other window')
self.QuitButton = QtWidgets.QPushButton ( "Quit" )
self.QContinueButton = QtWidgets.QPushButton ( "Continue" )
self.QuitButton.clicked.connect ( CM.close )
self.QWindowTwoButton.clicked.connect( lambda b=0, a= 400 : self.windowms(a))
layout.addWidget( self.QuitButton, 10, 1 )
layout.addWidget ( self.QContinueButton, 10, 2 )
layout.addWidget ( self.QWindowTwoButton, 10, 3 )
self.setLayout ( layout )
def windowms( self, a):
a = 100
self.switch_window.emit(a)
class Controller:
def __init__(self):
self.M = 5
self.S = 7
self.A = 8
# pass
def show_window_two(self):
self.window_two = WindowTwo(self.M, self.S)
self.window_two.switch_window.connect(self.show_window_three)
self.window_two.show()
def show_window_three(self):
try:
self.A = self.window_four.A
except:
pass
self.window_three = MS(self.M, self.S)
self.mscrollArea = QtWidgets.QScrollArea()
self.mscrollArea.setWidget(self.window_three)
self.mscrollArea.setDisabled(0)
self.window_three.switch_window.connect(self.show_window_four)
self.window_three.QuitButton.clicked.connect(self.mscrollArea.close)
self.mscrollArea.show()
self.mscrollArea.resize(700, 500)
self.mscrollArea.setWindowTitle("MS")
self.window_two.close()
try:
self.window_four.close()
except:
pass
def show_window_four(self, a):
if (a == 100):
self.window_four = WindowTwo(self.M, self.S)
self.window_four.switch_window.connect(self.show_window_three)
self.mscrollArea.setDisabled(1)
self.window_four.QuitButton.clicked.connect(lambda: self.window_four.close)
self.window_four.QuitButton.clicked.connect(lambda: self.mscrollArea.setDisabled(0))
self.window_four.show()
#Here is an else if a is other values to open other windows
def main():
app = QtWidgets.QApplication(sys.argv)
controller = Controller()
controller.show_window_two()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
【问题讨论】:
什么是show_first
?提供minimal reproducible example
谢谢,现在编辑,我的意思是 show_window_two()
M
中的self.QContinueButton.clicked.connect( lambda: self.windowms(M))
是什么,错误:Traceback (most recent call last): File "main.py", line 21, in <lambda> self.QContinueButton.clicked.connect( lambda: self.windowtwo(M)) NameError: name 'M' is not defined
请花时间确保您提供了一个可行的代码。
现在可以重现了!谢谢
【参考方案1】:
closeEvent 会在小部件关闭时触发,例如通过单击角落中的“X”。只需用您自己的代码覆盖它以再次显示主窗口,或发出信号通知您的控制器。
from PyQt5 import QtWidgets
app = QtWidgets.QApplication.instance() or QtWidgets.QApplication([])
class W1(QtWidgets.QWidget):
def closeEvent(self, event):
print("closing w1")
class W2(QtWidgets.QWidget):
def __init__(self, w1):
super().__init__()
self.w1 = w1
def closeEvent(self, event):
print("closing w2")
self.w1.show()
w1 = W1()
w2 = W2(w1)
w2.show()
app.exec_()
【讨论】:
以上是关于在 QtWidgets 的 PyQt5 中按下角落的红色 x 按钮时如何处理/覆盖?的主要内容,如果未能解决你的问题,请参考以下文章
如何检测在 PyQt5 中按下了动态添加的按钮之一? [复制]
Pylint 中的模块“PyQt5.QtWidgets”错误中没有名称“QApplication”
Pylint 中的模块“PyQt5.QtWidgets”错误中没有名称“QApplication”