Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt window focus events not called

I have a PyQt4 program where I'm trying to get notified when a window gets focus, following the advice in the QUndoGroup docs:

It is the programmer's responsibility to specify which stack is active by calling QUndoStack::setActive(), usually when the associated document window receives focus.

But I have a weird problem where only one window actually gets the focusIn and focusOut events, while the others either receive only one at their creation, or else never receive them at all. Here is an example program:



    #!/usr/bin/env python
    
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    import sys
    
    class MyWindow(QMainWindow):
        def __init__(self):
            super(MyWindow, self).__init__()
            self.label = QLabel('Window')
            self.setCentralWidget(self.label)
            self.setFocusPolicy(Qt.StrongFocus)
    
        def focusInEvent(self, event):
            self.label.setText('Got focus')
    
        def focusOutEvent(self, event):
            self.label.setText('Lost focus')
    
    def main():
        app = QApplication(sys.argv)
        win1 = MyWindow()
        win2 = MyWindow()
        win1.show()
        win2.show()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()

like image 671
J.C. Avatar asked Jan 18 '23 18:01

J.C.


1 Answers

I'm actually not quite sure why it doesn't work, might be an issue in how qt handles focus transition between windows. Anyways, below is how you might fix this, I've changed your code a bit

from PyQt4.QtCore import *
from PyQt4.QtGui import *

import sys

class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__()
        self.label = QLabel('Window')
        self.setCentralWidget(self.label)
        self.setFocusPolicy(Qt.StrongFocus)

    def focusInEvent(self, event):
        self.label.setText('Got focus')

    def focusOutEvent(self, event):
        self.label.setText('Lost focus')

def changedFocusSlot(old, now):
    if (now==None and QApplication.activeWindow()!=None):
        print "set focus to the active window"
        QApplication.activeWindow().setFocus()

def main():
    app = QApplication(sys.argv)
    QObject.connect(app, SIGNAL("focusChanged(QWidget *, QWidget *)"), changedFocusSlot)

    win1 = MyWindow()
    win2 = MyWindow()
    win1.show()
    win2.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main() 

hope this helps, regards

like image 82
serge_gubenko Avatar answered Jan 25 '23 14:01

serge_gubenko