Reputation: 9762
By installing an event filter, it is possible to see if a window has been activated/deactivated (QtCore.QEvent.WindowActivate
, QtCore.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.')
Is it possible to find out A) to which other window (of the same application) the focus was passed on, and B) whether the entire application was inactivated (that is: none of the windows is active)?
I wish the solution to be "minimal invasive" in that sense that I don't have to install event filters in all of my candidate windows. Is it possible to spy out other windows from within the current widget?
I'm interested in this information because I would like to capture some usage metrics for my application.
Upvotes: 2
Views: 601
Reputation: 243887
If you want to monitor the status of the windows you can use the notify method of QApplication:
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_())
Using the previous method I have implemented a signal that sends the activated window with the function 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_())
Upvotes: 2