Home > other >  PyQt5 - Detecting When Other Window Closes
PyQt5 - Detecting When Other Window Closes

Time:12-06

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):
  • Related