Search code examples
pythonpython-3.xpyqtpyqt5focus

How to capture PyQt5 QMainWindow losing focus


What I want to achieve: if a user clicks outside of the QMainWindow the window should hide.

How I tried to to tackle this problem: find a way to determine if the QMainWindow lost focus, and if so, hide the window using a followup function.

Unfortunately I can not totally grasp how to achieve this.

It can be done using the flag Qt::Popup but than I am not able to give any keyboard input to the widget my QMainWindow contains.


Solution

  • void QApplication::focusChanged(QWidget *old, QWidget *now)

    This signal is emitted when the widget that has keyboard focus changed from old to now, i.e., because the user pressed the tab-key, clicked into a widget or changed the active window. Both old and now can be the null-pointer.

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class MyWin(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            
            self.setFocus()
            QtWidgets.qApp.focusChanged.connect(self.on_focusChanged)       
    
        @QtCore.pyqtSlot("QWidget*", "QWidget*")
        def on_focusChanged(self, old, now):
    
            if now == None:
                print(f"\nwindow is the active window: {self.isActiveWindow()}")
                
                # window lost focus
                # do what you want
                
                self.setWindowState(QtCore.Qt.WindowMinimized)
                
            else: print(f"window is the active window: {self.isActiveWindow()}")
            
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        MainWindow = MyWin() 
        MainWindow.show()
        sys.exit(app.exec_())