I’m using PyQt5 and I need to have my main window detect when a different window closes. I read here Emit a signal from another class to main class that creating a signal class to serve as an intermediary should work. However I haven’t gotten my example to work.
In my example, clicking the button opens a QWidget window. When the QWidget is closed, the main window is supposed to change from a blue background to a red background. However, the main window remains blue using the script below.
What am I doing wrong?
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QObject, pyqtSignal
import os, sys
class MySignal(QObject):
signal = pyqtSignal()
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
#Make mainwindow
self.setGeometry(100,100,300,200)
self.setStyleSheet('background-color: blue')
# Make widget and button objects and set connection
self.widget = MyWidget()
self.btn = QPushButton(self)
self.btn.setText('Click')
self.btn.move(175, 150)
self.btn.setStyleSheet('background-color: white')
self.btn.clicked.connect(self.widget.showWidget)
# Make signal object and set connection
self.mySignal = MySignal()
self.mySignal.signal.connect(self.changeToRed)
# Let's start
self.show()
def changeToRed(self):
self.setStyleSheet('background-color: red')
def closeEvent(self, event):
os._exit(0)
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(500, 100, 200, 200)
self.sig = MySignal()
def showWidget(self):
self.show()
def closeEvent(self, event):
self.sig.signal.emit()
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyMainWindow()
app.exec()```
CodePudding user response:
The reason your code fails is that the connected signal object in MyMainWindow
is not the same as the one you create in MyWidget
, so the signal is never emitted. Here is a modified solution using signals in the normal way:
from PyQt5.QtWidgets import QPushButton, QMainWindow, QWidget, QApplication
from PyQt5.QtCore import QObject, pyqtSignal
import os, sys
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
#Make mainwindow
self.setGeometry(100,100,300,200)
self.setStyleSheet('background-color: blue')
# Make widget and button objects and set connection
self.widget = MyWidget()
self.btn = QPushButton(self)
self.btn.setText('Click')
self.btn.move(175, 150)
self.btn.setStyleSheet('background-color: white')
self.btn.clicked.connect(self.widget.showWidget)
self.widget.sig.connect(self.changeToRed)
# Let's start
self.show()
def changeToRed(self):
self.setStyleSheet('background-color: red')
class MyWidget(QWidget):
sig = pyqtSignal()
def __init__(self):
super().__init__()
self.setGeometry(500, 100, 200, 200)
def showWidget(self):
self.show()
def closeEvent(self, event):
self.sig.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyMainWindow()
app.exec()
CodePudding user response:
All you need is to add the connection between the close event and the function that turn your main screen red:
self.widget.closeEvent = self.changeToRed
this line should be in your main Window class
change your changeToRed function so it will except the event too:
def changeToRed(self, e):