如何找出“ WindowDeactivate”事件的焦点传递到哪个窗口?

时间:2019-05-10 22:29:30

标签: python pyqt pyqt5

通过安装事件过滤器,可以查看窗口是否已激活/停用(QtCore.QEvent.WindowActivateQtCore.QEvent.WindowDeactivate)。

class SomeWidget(QtWidgets.QWidget, object):
    # ...
    def __init__(self):
        # ...
        self.installEventFilter(self)
        # ...

    def eventFilter(self, object, event):
        if event.type() == QtCore.QEvent.WindowDeactivate:
            print('Window was deactivated.')
        if event.type() == QtCore.QEvent.WindowActivate:
            print('Window was activated.')

是否有可能找出A)焦点转移到(同一应用程序的)另一个窗口,以及B)整个应用程序是否未激活(即:没有一个窗口处于活动状态)?

我希望该解决方案是“微创”的,因为我不必在所有候选窗口中都安装事件过滤器。是否可以从当前小部件中窥探其他窗口?

我对这些信息感兴趣,因为我想捕获应用程序的一些使用指标。

1 个答案:

答案 0 :(得分:2)

如果要监视窗口的状态,可以使用QApplication的notify方法:

from PyQt5 import QtCore, QtWidgets


class Application(QtWidgets.QApplication):
    def notify(self, obj, event):
        if event.type() == QtCore.QEvent.WindowDeactivate:
            print("{} was deactivated:".format(obj))
        if event.type() == QtCore.QEvent.WindowActivate:
            print("{} was activated.".format(obj))
        return super().notify(obj, event)


if __name__ == "__main__":
    import sys

    app = Application(sys.argv)
    windows = []
    for _ in range(3):
        w = QtWidgets.QWidget()
        w.show()
        windows.append(w)
    sys.exit(app.exec_())

使用先前的方法,我实现了一个信号,该信号使用功能QApplication :: activeWindow()发送已激活的窗口:

from PyQt5 import QtCore, QtWidgets


class Application(QtWidgets.QApplication):
    activateChanged = QtCore.pyqtSignal(QtWidgets.QWidget)

    def __init__(self, l):
        super().__init__(l)
        self._window_activate = None

    def notify(self, obj, event):
        if event.type() == QtCore.QEvent.WindowDeactivate:
            QtCore.QTimer.singleShot(0, self.on_timeout)
        if event.type() == QtCore.QEvent.WindowActivate:
            QtCore.QTimer.singleShot(0, self.on_timeout)
        return super().notify(obj, event)

    def on_timeout(self):
        if self._window_activate != QtWidgets.QApplication.activeWindow():
            self._window_activate = QtWidgets.QApplication.activeWindow()
            self.activateChanged.emit(self._window_activate)


if __name__ == "__main__":
    import sys

    app = Application(sys.argv)
    app.activateChanged.connect(print)
    windows = []
    for _ in range(5):
        w = QtWidgets.QWidget()
        w.show()
        windows.append(w)
    sys.exit(app.exec_())