Wie kann ich die Anzeige Leerlaufzeit von Python in Windows, Linux und MacOS bestimmen?
Frage
Ich möchte wissen, wie lange es her ist, seit der Benutzer zuletzt eine Taste drücken oder die Maus bewegt - nicht nur in meiner Anwendung, aber im Großen und Ganzen „Computer“ (dh Display), um zu erraten, ob sie noch am Computer und in der Lage Benachrichtigungen zu beobachten, die auf dem Bildschirm eingeblendet.
Ich möchte, dies zu tun rein aus (Py) GTK +, aber ich bin offen für Aufruf plattformspezifische Funktionen. Ich würde am liebsten Funktionen aufrufen, die bereits von Python eingewickelt wurden, aber wenn das nicht möglich ist, ich bin nicht über ein wenig C oder ctypes
Code, solange ich weiß, was ich eigentlich suchen.
Unter Windows Ich denke, die Funktion, die ich will, ist GetLastInputInfo
, aber das scheint nicht von pywin32 gewickelt zu werden; Ich hoffe, ich bin etwas fehlt.
Lösung
Gajim tut es auf diese Weise unter Windows, OS X und GNU / Linux (und andere * nixes) :
- Python-Wrapper-Modul (auch enthält Erkennungscode Windows-Leerlaufzeit, mit
GetTickCount
mitctypes
); - Ctypes-basierte Modul X11 Leerlaufzeit zu erhalten (mit
XScreenSaverQueryInfo
, war ein C-Modul in alten Gajim Versionen); - C Modul OS X Leerlauf zu erhalten Zeit (
HIDIdleTime
Systemeigenschaft verwendet wird).
Diese Links sind ziemlich veraltet 0,12 Version, so dass Sie Stromquelle überprüfen, für mögliche weitere Verbesserungen und Änderungen können wollen.
Andere Tipps
Wenn Sie PyGTK und X11 auf Linux verwenden, können Sie etwas tun, das darauf basiert, was Pidgin tut:
import ctypes
import ctypes.util
import platform
class XScreenSaverInfo(ctypes.Structure):
_fields_ = [('window', ctypes.c_long),
('state', ctypes.c_int),
('kind', ctypes.c_int),
('til_or_since', ctypes.c_ulong),
('idle', ctypes.c_ulong),
('eventMask', ctypes.c_ulong)]
class IdleXScreenSaver(object):
def __init__(self):
self.xss = self._get_library('Xss')
self.gdk = self._get_library('gdk-x11-2.0')
self.gdk.gdk_display_get_default.restype = ctypes.c_void_p
# GDK_DISPLAY_XDISPLAY expands to gdk_x11_display_get_xdisplay
self.gdk.gdk_x11_display_get_xdisplay.restype = ctypes.c_void_p
self.gdk.gdk_x11_display_get_xdisplay.argtypes = [ctypes.c_void_p]
# GDK_ROOT_WINDOW expands to gdk_x11_get_default_root_xwindow
self.gdk.gdk_x11_get_default_root_xwindow.restype = ctypes.c_void_p
self.xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo)
self.xss.XScreenSaverQueryExtension.restype = ctypes.c_int
self.xss.XScreenSaverQueryExtension.argtypes = [ctypes.c_void_p,
ctypes.POINTER(ctypes.c_int),
ctypes.POINTER(ctypes.c_int)]
self.xss.XScreenSaverQueryInfo.restype = ctypes.c_int
self.xss.XScreenSaverQueryInfo.argtypes = [ctypes.c_void_p,
ctypes.c_void_p,
ctypes.POINTER(XScreenSaverInfo)]
# gtk_init() must have been called for this to work
import gtk
gtk # pyflakes
# has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
# &event_base, &error_base);
event_base = ctypes.c_int()
error_base = ctypes.c_int()
gtk_display = self.gdk.gdk_display_get_default()
self.dpy = self.gdk.gdk_x11_display_get_xdisplay(gtk_display)
available = self.xss.XScreenSaverQueryExtension(self.dpy,
ctypes.byref(event_base),
ctypes.byref(error_base))
if available == 1:
self.xss_info = self.xss.XScreenSaverAllocInfo()
else:
self.xss_info = None
def _get_library(self, libname):
path = ctypes.util.find_library(libname)
if not path:
raise ImportError('Could not find library "%s"' % (libname, ))
lib = ctypes.cdll.LoadLibrary(path)
assert lib
return lib
def get_idle(self):
if not self.xss_info:
return 0
# XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
# GDK_ROOT_WINDOW(), mit_info);
drawable = self.gdk.gdk_x11_get_default_root_xwindow()
self.xss.XScreenSaverQueryInfo(self.dpy, drawable, self.xss_info)
# return (mit_info->idle) / 1000;
return self.xss_info.contents.idle / 1000
Das obige Beispiel nutzt über ctypes gdk Lage sein, die X11-spezifischen zuzugreifen. Xscreensaver APIs müssen auch über ctypes zugegriffen werden kann.
Es sollte ziemlich einfach zu portieren, es pYGI und Innerlichkeit zu verwenden.
Ich habe eine Antwort in Bezug auf Mausklicks was darauf hindeutet, pyHook :
Detecting Mausklicks in Fenstern mit Python
Hier ist ein anderer Code, den ich tat Maus-Position über ctypes zu erkennen: http://monkut.webfactional.com/ Blog / Archiv / 2008/10/2 / python-win-Maus-Position
Eine Rund über Verfahren, um dies zu erreichen, würde über Screen-Capture und jede Änderung in Bildern mit PIL verglichen wird.
http: / /www.wellho.net/forum/Programming-in-Python-and-Ruby/Python-Imaging-Library-PIL.html