2009-12-07 3 views
4

필자는 키보드의 Super (또는 WinKey) 키를 누를 때마다 이벤트를 실행해야하는 python 스크립트를 만들었습니다.파이썬 (백그라운드의 데몬)을 사용하여 키가 눌러 졌는지 확인하십시오.

키스톤이 이벤트를 실행하기 위해 대기하는 백그라운드에서 실행중인 것처럼 파이썬 프로세스가 "집중"하지 않고 어떻게이 작업을 수행 할 수 있습니까?

입력 내용을 읽는 방법을 보여주는 웹에서 많은 게시물을 보았습니다. 그러나 프로세스에 "집중"해야하는 사람이 있었지만 아무도 나에게 Super (또는 WinKey) 캡처 방법을 알려주지 않았습니다. 파이썬 스크립트.

저는 우분투 9.10을 사용하고 있습니다.

답변

5

일이 내 * nix에서 스크립트수정의 상태가 키를 얻을 수 없습니다 체계.

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
"""OSD Neo2 
    ======== 
    On screen display for learning the keyboard layout Neo2 
    Copyright (c) 2009 Martin Zuther (http://www.mzuther.de/) 
    This program is free software: you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation, either version 3 of the License, or 
    (at your option) any later version. 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    GNU General Public License for more details. 
    You should have received a copy of the GNU General Public License 
    along with this program. If not, see <http://www.gnu.org/licenses/>. 
    Thank you for using free software! 
""" 
# Here follows a plea in German to keep the comments in English so 
# that you may understand them, dear visitor ... 
# 
# Meine Kommentare in den Quellcodes sind absichtlich auf Englisch 
# gehalten, damit Leute, die im Internet nach Lösungen suchen, den 
# Code nachvollziehen können. Daher bitte ich darum, zusätzliche 
# Kommentare ebenfalls auf Englisch zu schreiben. Vielen Dank! 
import ctypes 
import ctypes.util 
import gettext 
import os 
import types 
# initialise localisation settings 
module_path = os.path.dirname(os.path.realpath(__file__)) 
gettext.bindtextdomain('OSDneo2', os.path.join(module_path, 'po/')) 
gettext.textdomain('OSDneo2') 
_ = gettext.lgettext 
class SimpleXkbWrapper: 
    """ 
    Far from complete wrapper for the "X Keyboard Extension" (well, to 
    be honest, it just wraps what I need using Python's "ctypes" 
    library <g>). 
    """ 
    # set this to true to get lots of debugging information (and 
    # considerably slow things down) 
    DEBUG_XKB = False 
    # "C defines" from file /usr/include/X11/extensions/XKB.h (Ubuntu 9.04): 
    # $XFree86: xc/include/extensions/XKB.h,v 1.5tsi Exp $ 
    # 
    # XkbUseCoreKbd is used to specify the core keyboard without having to 
    # look up its X input extension identifier. 
    XkbUseCoreKbd   = 0x0100 
    # "C defines" from file /usr/include/X11/XKBlib.h (Ubuntu 9.04): 
    # $XFree86: xc/lib/X11/XKBlib.h,v 3.5 2003/04/17 02:06:31 dawes Exp $ # 
    # 
    # XkbOpenDisplay error codes 
    XkbOD_Success   = 0 
    XkbOD_BadLibraryVersion = 1 
    XkbOD_ConnectionRefused = 2 
    XkbOD_NonXkbServer  = 3 
    XkbOD_BadServerVersion = 4 
    # "C typedef" from file /usr/include/X11/extensions/XKBstr.h (Ubuntu 9.04): 
    # $Xorg: XKBstr.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ 
    # 
    # Common data structures and access macros 
    # 
    # typedef struct _XkbStateRec { 
    #   unsigned char group; 
    #   unsigned char locked_group; 
    #   unsigned short base_group; 
    #   unsigned short latched_group; 
    #   unsigned char mods; 
    #   unsigned char base_mods; 
    #   unsigned char latched_mods; 
    #   unsigned char locked_mods; 
    #   unsigned char compat_state; 
    #   unsigned char grab_mods; 
    #   unsigned char compat_grab_mods; 
    #   unsigned char lookup_mods; 
    #   unsigned char compat_lookup_mods; 
    #   unsigned short ptr_buttons; 
    # } XkbStateRec,*XkbStatePtr; 
    class XkbStateRec(ctypes.Structure): 
     _fields_ = [ 
         ('group',    ctypes.c_ubyte), \ 
         ('locked_group',  ctypes.c_ubyte), \ 
         ('base_group',   ctypes.c_ushort), \ 
         ('latched_group',  ctypes.c_ushort), \ 
         ('mods',    ctypes.c_ubyte), \ 
         ('base_mods',   ctypes.c_ubyte), \ 
         ('latched_mods',  ctypes.c_ubyte), \ 
         ('locked_mods',  ctypes.c_ubyte), \ 
         ('compat_state',  ctypes.c_ubyte), \ 
         ('grab_mods',   ctypes.c_ubyte), \ 
         ('compat_grab_mods', ctypes.c_ubyte), \ 
         ('lookup_mods',  ctypes.c_ubyte), \ 
         ('compat_lookup_mods', ctypes.c_ubyte), \ 
         ('ptr_buttons',  ctypes.c_ushort) \ 
        ] 
    # "C defines" from file /usr/include/X11/X.h (Ubuntu 9.04): 
    # $XFree86: xc/include/X.h,v 1.6 2003/07/09 15:27:28 tsi Exp $ 
    # 
    # Key masks. Used as modifiers to GrabButton and GrabKey, results of 
    # QueryPointer, state in various key-, mouse-, and button-related 
    # events. 
    ShiftMask    = 1 
    LockMask     = 2 
    ControlMask    = 4 
    Mod1Mask     = 8 
    Mod2Mask     = 16 
    Mod3Mask     = 32 
    Mod4Mask     = 64 
    Mod5Mask     = 128 
    def __init__(self): 
     # dynamically link to "X Keyboard Extension" library 
     library_xf86misc = ctypes.CDLL(ctypes.util.find_library('Xxf86misc')) 
     # print debugging information if requested 
     if self.DEBUG_XKB: 
      print 
      print ' %s' % library_xf86misc 
     # define "ctypes" prototype for the function 
     # 
     # Display *XkbOpenDisplay(display_name, event_rtrn, error_rtrn, 
     #        major_in_out, minor_in_out, reason_rtrn) 
     # 
     # char * display_name; 
     # int * event_rtrn; 
     # int * error_rtrn; 
     # int * major_in_out; 
     # int * minor_in_out; 
     # int * reason_rtrn; 
     paramflags_xkbopendisplay = \ 
      (1, 'display_name'), \ 
      (2, 'event_rtrn'), \ 
      (2, 'error_rtrn'), \ 
      (3, 'major_in_out'), \ 
      (3, 'minor_in_out'), \ 
      (2, 'reason_rtrn') 
     prototype_xkbopendisplay = ctypes.CFUNCTYPE(\ 
      ctypes.c_uint, \ 
       ctypes.c_char_p, \ 
       ctypes.POINTER(ctypes.c_int), \ 
       ctypes.POINTER(ctypes.c_int), \ 
       ctypes.POINTER(ctypes.c_int), \ 
       ctypes.POINTER(ctypes.c_int), \ 
       ctypes.POINTER(ctypes.c_int) \ 
       ) 
     # set-up function (low-level) 
     self.__XkbOpenDisplay__ = prototype_xkbopendisplay(\ 
      ('XkbOpenDisplay', library_xf86misc), \ 
       paramflags_xkbopendisplay \ 
       ) 
     # define error handler 
     def errcheck_xkbopendisplay(result, func, args): 
      # print debugging information if requested 
      if self.DEBUG_XKB: 
       print 
       print ' [XkbOpenDisplay]' 
       print ' Display:  %#010x' % result 
       print ' display_name: %s' % args[0].value 
       print ' event_rtrn: %d' % args[1].value 
       print ' error_rtrn: %d' % args[2].value 
       print ' major_in_out: %d' % args[3].value 
       print ' minor_in_out: %d' % args[4].value 
       print ' reason_rt:  %d' % args[5].value 
      # function didn't return display handle, so let's see why 
      # not 
      if result == 0: 
       # values were taken from file /usr/include/X11/XKBlib.h (Ubuntu 9.04): 
       # $XFree86: xc/lib/X11/XKBlib.h,v 3.5 2003/04/17 02:06:31 dawes Exp $ # 
       error_id = args[5].value 
       if error_id == self.XkbOD_Success: 
        error_name = 'XkbOD_Success' 
       elif error_id == self.XkbOD_BadLibraryVersion: 
        error_name = 'XkbOD_BadLibraryVersion' 
       elif error_id == self.XkbOD_ConnectionRefused: 
        error_name = 'XkbOD_ConnectionRefused' 
       elif error_id == self.XkbOD_NonXkbServer: 
        error_name = 'XkbOD_NonXkbServer' 
       elif error_id == self.XkbOD_BadServerVersion: 
        error_name = 'XkbOD_BadServerVersion' 
       else: 
        error_name = _('undefined') 
       error_message = \ 
        _('"XkbOpenDisplay" reported an error (%(error_name)s).') % \ 
        {'error_name': error_name} 
       raise OSError(error_message) 
      # return display handle and all function arguments 
      return (ctypes.c_uint(result), args) 
     # connect error handler to function 
     self.__XkbOpenDisplay__.errcheck = errcheck_xkbopendisplay 
     # define "ctypes" prototype for the function 
     # 
     # Bool XkbGetState(display, device_spec, state_return) 
     # 
     #  Display *    display; 
     #  unsigned int   device_spec; 
     #  XkbStatePtr   state_return; 
     paramflags_xkbgetstate = \ 
      (1, 'display'), \ 
      (1, 'device_spec'), \ 
      (3, 'state_return') 
     prototype_xkbgetstate = ctypes.CFUNCTYPE(\ 
      ctypes.c_int, # Python 2.5 doesn't yet know c_bool \ 
       ctypes.c_uint, \ 
       ctypes.c_uint, \ 
       ctypes.POINTER(self.XkbStateRec) \ 
       ) 
     # set-up function (low-level) 
     self.__XkbGetState__ = prototype_xkbgetstate(\ 
      ('XkbGetState', library_xf86misc), \ 
       paramflags_xkbgetstate \ 
       ) 
     # define error handler 
     def errcheck_xkbgetstate(result, func, args): 
      # print debugging information if requested 
      if self.DEBUG_XKB: 
       print 
       print ' [XkbGetState]' 
       print ' Status:  %s' % result 
       print ' display:  %#010x' % args[0].value 
       print ' device_spec: %d\n' % args[1].value 
       print ' state_return.group:    %d' % \ 
        args[2].group 
       print ' state_return.locked_group:  %d' % \ 
        args[2].locked_group 
       print ' state_return.base_group:   %d' % \ 
        args[2].base_group 
       print ' state_return.latched_group:  %d' % \ 
        args[2].latched_group 
       print ' state_return.mods:    %d' % \ 
        args[2].mods 
       print ' state_return.base_mods:   %d' % \ 
        args[2].base_mods 
       print ' state_return.latched_mods:  %d' % \ 
        args[2].latched_mods 
       print ' state_return.locked_mods:   %d' % \ 
        args[2].locked_mods 
       print ' state_return.compat_state:  %d' % \ 
        args[2].compat_state 
       print ' state_return.grab_mods:   %d' % \ 
        args[2].grab_mods 
       print ' state_return.compat_grab_mods: %d' % \ 
        args[2].compat_grab_mods 
       print ' state_return.lookup_mods:   %d' % \ 
        args[2].lookup_mods 
       print ' state_return.compat_lookup_mods: %d' % \ 
        args[2].compat_lookup_mods 
       print ' state_return.ptr_buttons:   %d\n' % \ 
        args[2].ptr_buttons 
       print ' Mask   mods base_mods latched_mods locked_mods compat_state' 
       print ' --------------------------------------------------------------------------' 
       print ' ShiftMask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.ShiftMask) != 0, \ 
        (args[2].base_mods & self.ShiftMask) != 0, \ 
        (args[2].latched_mods & self.ShiftMask) != 0, \ 
        (args[2].locked_mods & self.ShiftMask) != 0, \ 
        (args[2].compat_state & self.ShiftMask) != 0) 
       print ' LockMask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.LockMask) != 0, \ 
        (args[2].base_mods & self.LockMask) != 0, \ 
        (args[2].latched_mods & self.LockMask) != 0, \ 
        (args[2].locked_mods & self.LockMask) != 0, \ 
        (args[2].compat_state & self.LockMask) != 0) 
       print ' ControlMask %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.ControlMask) != 0, \ 
        (args[2].base_mods & self.ControlMask) != 0, \ 
        (args[2].latched_mods & self.ControlMask) != 0, \ 
        (args[2].locked_mods & self.ControlMask) != 0, \ 
        (args[2].compat_state & self.ControlMask) != 0) 
       print ' Mod1Mask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.Mod1Mask) != 0, \ 
        (args[2].base_mods & self.Mod1Mask) != 0, \ 
        (args[2].latched_mods & self.Mod1Mask) != 0, \ 
        (args[2].locked_mods & self.Mod1Mask) != 0, \ 
        (args[2].compat_state & self.Mod1Mask) != 0) 
       print ' Mod2Mask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.Mod2Mask) != 0, \ 
        (args[2].base_mods & self.Mod2Mask) != 0, \ 
        (args[2].latched_mods & self.Mod2Mask) != 0, \ 
        (args[2].locked_mods & self.Mod2Mask) != 0, \ 
        (args[2].compat_state & self.Mod2Mask) != 0) 
       print ' Mod3Mask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.Mod3Mask) != 0, \ 
        (args[2].base_mods & self.Mod3Mask) != 0, \ 
        (args[2].latched_mods & self.Mod3Mask) != 0, \ 
        (args[2].locked_mods & self.Mod3Mask) != 0, \ 
        (args[2].compat_state & self.Mod3Mask) != 0) 
       print ' Mod4Mask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.Mod4Mask) != 0, \ 
        (args[2].base_mods & self.Mod4Mask) != 0, \ 
        (args[2].latched_mods & self.Mod4Mask) != 0, \ 
        (args[2].locked_mods & self.Mod4Mask) != 0, \ 
        (args[2].compat_state & self.Mod4Mask) != 0) 
       print ' Mod5Mask  %-5s %-5s  %-5s   %-5s   %-5s' % \ 
        ((args[2].mods   & self.Mod5Mask) != 0, \ 
        (args[2].base_mods & self.Mod5Mask) != 0, \ 
        (args[2].latched_mods & self.Mod5Mask) != 0, \ 
        (args[2].locked_mods & self.Mod5Mask) != 0, \ 
        (args[2].compat_state & self.Mod5Mask) != 0) 
      # return function return value and all function arguments 
      return (result, args) 
     # connect error handler to function 
     self.__XkbGetState__.errcheck = errcheck_xkbgetstate 
    # define high-level version of "XkbOpenDisplay" 
    def XkbOpenDisplay(self, display_name, major_in_out, minor_in_out): 
     # if we don't do type checking, nobody ever will 
     assert (type(display_name) == types.NoneType) or \ 
      (type(display_name) == types.StringType) 
     assert type(major_in_out) == types.IntType 
     assert type(minor_in_out) == types.IntType 
     # convert function arguments to "ctypes", ... 
     __display_name__ = ctypes.c_char_p(display_name) 
     __major_in_out__ = ctypes.c_int(major_in_out) 
     __minor_in_out__ = ctypes.c_int(minor_in_out) 
     # ... call low-level function ... 
     ret = self.__XkbOpenDisplay__(__display_name__, __major_in_out__, \ 
             __minor_in_out__) 
     # ... and return converted return value and function arguments 
     return {'display_handle': ret[0].value, \ 
        'server_major_version': ret[1][3].value, \ 
        'server_minor_version': ret[1][4].value} 
    # define high-level version of "XkbGetState" 
    def XkbGetState(self, display_handle, device_spec): 
     # if we don't do type checking, nobody ever will 
     assert type(display_handle) == types.LongType 
     assert type(device_spec) == types.IntType 
     # convert function arguments to "ctypes", ... 
     __display_handle__ = ctypes.c_uint(display_handle) 
     __device_spec__ = ctypes.c_uint(device_spec) 
     __xkbstaterec__ = self.XkbStateRec() 
     # ... call low-level function ... 
     ret = self.__XkbGetState__(__display_handle__, __device_spec__, \ 
            __xkbstaterec__) 
     # ... and return converted function argument 
     xkbstaterec = ret[1][2] 
     return xkbstaterec 
    # extract modifier status using bitmasks 
    def ExtractLocks(self, xkbstaterec): 
     return {'group': xkbstaterec.group, \ 
       'shift': \ 
        (xkbstaterec.base_mods & self.ShiftMask) != 0, \ 
       'shift_lock': \ 
        (xkbstaterec.locked_mods & self.ShiftMask) != 0, \ 
       'lock': \ 
        (xkbstaterec.base_mods & self.LockMask) != 0, \ 
       'lock_lock': \ 
        (xkbstaterec.locked_mods & self.LockMask) != 0, \ 
       'control': \ 
        (xkbstaterec.base_mods & self.ControlMask) != 0, \ 
       'control_lock': \ 
        (xkbstaterec.locked_mods & self.ControlMask) != 0, \ 
       'mod1': \ 
        (xkbstaterec.base_mods & self.Mod1Mask) != 0, \ 
       'mod1_lock': \ 
        (xkbstaterec.locked_mods & self.Mod1Mask) != 0, \ 
       'mod2': \ 
        (xkbstaterec.base_mods & self.Mod2Mask) != 0, \ 
       'mod2_lock': \ 
        (xkbstaterec.locked_mods & self.Mod2Mask) != 0, \ 
       'mod3': \ 
        (xkbstaterec.base_mods & self.Mod3Mask) != 0, \ 
       'mod3_lock': \ 
        (xkbstaterec.locked_mods & self.Mod3Mask) != 0, \ 
       'mod4': \ 
        (xkbstaterec.base_mods & self.Mod4Mask) != 0, \ 
       'mod4_lock': \ 
        (xkbstaterec.locked_mods & self.Mod4Mask) != 0, \ 
       'mod5': \ 
        (xkbstaterec.base_mods & self.Mod5Mask) != 0, \ 
       'mod5_lock': \ 
        (xkbstaterec.locked_mods & self.Mod5Mask) != 0} 

from FILENAME import *를 호출하고 다음과 같이 다른 파일에서, 사전에 상태를 호출하려면 : 그리기위한 Jason Orendorffl에 코드 here를 찾을 수있는 창조자에

# simple demonstration of this wrapper 
xkb = SimpleXkbWrapper() 
# initialise wrapper for the X Keyboard Extension (v1.0) and 
# open connection to default X display 
display_name = None 
major_in_out = 1 
minor_in_out = 0 
try: 
    ret = xkb.XkbOpenDisplay(display_name, major_in_out, minor_in_out) 
except OSError, error: 
    print 
    print ' Error: %s' % error 
    print 
    exit(1) 
# ... get modifier state of core keyboard ... 
display_handle = ret['display_handle'] 
device_spec = xkb.XkbUseCoreKbd 
xkbstaterec = xkb.XkbGetState(display_handle, device_spec) 
# ... and extract and the information we need 
print xkb.ExtractLocks(xkbstaterec) 

건배를하고, 내 그것에주의를 기울이십시오.

0

Linux에서 작업해야하는 경우 X 이벤트를 어떻게 든 모니터링해야한다고 생각합니다.

"xev"명령을 실행하면 모든 이벤트를 볼 수 있습니다. 따라서 X가 모든 이벤트에 대한 인터페이스를 제공한다고 확신합니다. 빠른 인터넷 검색은 아마도 당신에게 필요한 물건을 제공 Python X library을 찾습니다.

download it here하실 수 있습니다.

+2

이 키보드를 듣고 초점을 필요로한다. – jfs

+0

당신이 맞습니다. 그래서 그 대답은 잘못되었습니다, 미안 해요. 새로운 코드를 게시하십시오 :) – Kimvais

+1

XQueryPointer를 사용하면이 코드가 믿어지면 포커스를 사용하지 않고 키보드 변경자 키 상태를 폴링 할 수 있습니다. http://synergy2.cvs.sourceforge.net/viewvc/synergy2/synergy/ –

2

내 이전 대답은 분명히 완전히 잘못되었습니다. 미안합니다. 나는 올바른 접근 방식은/dev/입 /합니다 Event1에서 읽을 수있을 거라고 생각

이 짧은 테스트가 나를 위해 스캔 코드를 보여, 터미널에 포커스되어 있지 않은 경우에도 (?) : 내가 할

from struct import unpack 
port = open("/dev/input/event1","rb")  

while 1:  
    a,b,c,d = unpack("4B",port.read(4))  
    print a,b,c,d 

을 는/dev/입 /합니다 Event1은 항상 키보드 나 방법 중 하나가 결정하는 경우 알고 있지만, 적어도 나에게는

+0

Ok USB 키보드의 파일을 사용하여 event3에 연결된 파일을 찾습니다. 나는 일련의 스캔 코드를 얻는다. 그러나 그들은 결코 동일하지 않다. XD로 인터넷 검색. – torger

+0

스캔 코드에 대해 잘 모릅니다. – torger

0

이러한 목적으로 PyUserInput을 사용할 수 있습니다.이 방법은 X11과 호환되는 교차 플랫폼 솔루션입니다. 슈퍼와

예 :

from pykeyboard import PyKeyboardEvent 

class MonitorSuper(PyKeyboardEvent): 
    def tap(self, keycode, character, press): 
     '''Monitor Super key.''' 
     if character == 'Super_L': 
      if press: 
       print('Super pressed') 
      else: 
       print('Super released') 
mon = MonitorSuper() 
mon.run() 
관련 문제