PyQt窗口焦点事件未调用

4
我有一个PyQt4程序,试图按照QUndoGroup文档中的建议,在窗口获得焦点时收到通知:
通常在关联的文档窗口接收到焦点时,调用QUndoStack :: setActive()指定哪个堆栈是活动的是程序员的责任。
但是我遇到了一个奇怪的问题,只有一个窗口实际上会收到焦点进入和离开事件,而其他窗口则在创建时只收到一次或根本不收到。下面是一个示例程序:


    #!/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()


这在这里可以工作,但这取决于您的窗口管理器如何处理键盘焦点。简单地将鼠标移动到其中一个上面并不一定会使其获得键盘焦点。通常需要在内部单击。键盘焦点是否在鼠标移出时丢失取决于窗口管理器。 - Mat
1
缩小了范围。我不知道为什么以前没有注意到,但是当您单击窗口内部时,它确实可以工作,但是当您单击窗口标题栏或 alt+tab 切换到该窗口时则不能工作。然后它会像所描述的那样工作,其中一个窗口正确地接收到所有事件,而另一个窗口则不会接收。 - J.C.
1个回答

9

我其实不太确定为什么它不起作用,可能与qt处理窗口之间焦点转移的方式有关。无论如何,以下是您可能修复此问题的方法,我已经稍微修改了您的代码。

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() 

希望这能帮到您,祝好!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接