18

ユーザーが最後にキーを押したり、マウスを動かしたりしてから、アプリケーションだけでなく、「コンピューター」全体 (つまり、ディスプレイ) でどのくらいの時間が経過したかを知りたいです。コンピューターに接続し、画面にポップアップする通知を観察できます。

これを純粋に (Py)GTK+ から実行したいのですが、プラットフォーム固有の関数を呼び出すことはできます。理想的には、すでに Python からラップされている関数を呼び出したいのですが、それが不可能な場合でも、ctypes実際に何を探しているかを知っている限り、C やコードの知識はあまりありません。

Windows では、必要な機能は だと思いますがGetLastInputInfo、それは pywin32 によってラップされていないようです。何かが足りないことを願っています。

4

3 に答える 3

12

Gajimは、Windows、OS X、および GNU/Linux (およびその他の *nix) で次のようにします。

  1. Python ラッパー モジュールGetTickCount( withを使用した Windows アイドル時間検出コードも含まれますctypes);
  2. X11 のアイドル時間を取得するための Ctypes ベースのモジュールXScreenSaverQueryInfo(古い Gajim バージョンでは C モジュールであったを使用);
  3. OS X のアイドル時間を取得する C モジュール(HIDIdleTimeシステム プロパティを使用)。

これらのリンクはかなり古いバージョンの 0.12 へのものであるため、現在のソースを確認して、さらなる改善や変更の可能性を確認してください。

于 2009-07-17T21:07:04.147 に答える
7

Linux で PyGTK と X11 を使用する場合、Pidgin の機能に基づいて、次のようなことができます。

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

上記の例では、ctypes を介して gdk を使用して、X11 固有にアクセスできるようにしています。Xscreensaver API にも ctypes 経由でアクセスする必要があります。

PyGI とイントロスペクションを使用するように移植するのはかなり簡単なはずです。

于 2013-05-27T17:06:43.560 に答える
2

pyHookの使用を提案するマウスクリックに関する回答を得ました:

Pythonを使用したWindowsでのマウスクリックの検出

ctypesを介してマウスの位置を検出するために行った他のコードは次のとおりです。http: //monkut.webfactional.com/blog/archive/2008/10/2/python-win-mouse-position

これを実現するためのより回りくどい方法は、スクリーンキャプチャを使用し、PILを使用して画像の変化を比較することです。

http://www.wellho.net/forum/Programming-in-Python-and-Ruby/Python-Imaging-Library-PIL.html

于 2008-10-20T01:27:38.613 に答える