Heim > Backend-Entwicklung > Python-Tutorial > Wie erkenne ich Tastatureingaben in einem Python-Skript, das vom Terminal aus ausgeführt wird?

Wie erkenne ich Tastatureingaben in einem Python-Skript, das vom Terminal aus ausgeführt wird?

DDD
Freigeben: 2024-10-29 12:37:02
Original
1038 Leute haben es durchsucht

How do I detect keyboard input in a Python script running from the terminal?

Wie erkennt man Tastatureingaben in einem Skript vom Terminal aus?

Synchronisierte/blockierende Tastenerfassung:

Eine einfache Eingabe oder raw_input, eine Blockierung Funktion, die von einem Benutzer eingegebenen Text zurückgibt, sobald er eine neue Zeile drückt.

<code class="python">typedString = raw_input()</code>
Nach dem Login kopieren

Eine einfache Blockierungsfunktion, die darauf wartet, dass der Benutzer eine einzelne Taste drückt, und diese Taste dann zurückgibt

<code class="python">class _Getch:
 &quot;&quot;&quot;Gets a single character from standard input.  Does not echo to the
screen. From http://code.activestate.com/recipes/134892/&quot;&quot;&quot;
def __init__(self):
  try:
    self.impl = _GetchWindows()
  except ImportError:
    try:
      self.impl = _GetchMacCarbon()
    except(AttributeError, ImportError):
      self.impl = _GetchUnix()

def __call__(self): return self.impl()


class _GetchUnix:
def __init__(self):
  import tty, sys, termios # import termios now or else you'll get the Unix version on the Mac

def __call__(self):
  import sys, tty, termios
  fd = sys.stdin.fileno()
  old_settings = termios.tcgetattr(fd)
  try:
    tty.setraw(sys.stdin.fileno())
    ch = sys.stdin.read(1)
  finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
  return ch

class _GetchWindows:
def __init__(self):
  import msvcrt

def __call__(self):
  import msvcrt
  return msvcrt.getch()

class _GetchMacCarbon:
&quot;&quot;&quot;
A function which returns the current ASCII key that is down;
if no ASCII key is down, the null string is returned.  The
page http://www.mactech.com/macintosh-c/chap02-1.html was
very helpful in figuring out how to do this.
&quot;&quot;&quot;
def __init__(self):
  import Carbon
  Carbon.Evt #see if it has this (in Unix, it doesn't)

def __call__(self):
  import Carbon
  if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask
    return ''
  else:
    #
    # The event contains the following info:
    # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
    #
    # The message (msg) contains the ASCII char which is
    # extracted with the 0x000000FF charCodeMask; this
    # number is converted to an ASCII character with chr() and
    # returned
    #
    (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
    return chr(msg &amp; 0x000000FF)


def getKey():
  inkey = _Getch()
  import sys
  for i in xrange(sys.maxint):
    k=inkey()
    if k<>'':break

  return k</code>
Nach dem Login kopieren

Asynchrone Schlüsselerfassung:

Ein Rückruf, der mit der gedrückten Taste immer dann aufgerufen wird, wenn der Benutzer eine Taste in die Eingabeaufforderung eingibt, auch wenn er Dinge in einen Interpreter (einen Keylogger) eingibt

Rückrufe wurden noch nicht implementiert.

Ein Rückruf, der mit dem eingegebenen Text aufgerufen wird, nachdem der Benutzer die Eingabetaste drückt (ein weniger Echtzeit-Keylogger)

Rückrufe wurden noch nicht implementiert implementiert.

Ein Rückruf, der mit gedrückten Tasten aufgerufen wird, wenn ein Programm ausgeführt wird (z. B. in einer for-Schleife oder while-Schleife)

Windows:

<code class="python">import threading
from win32api import STD_INPUT_HANDLE
from win32console import GetStdHandle, KEY_EVENT, ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT


class KeyAsyncReader():
  def __init__(self):
    self.stopLock = threading.Lock()
    self.stopped = True
    self.capturedChars = &quot;&quot;

    self.readHandle = GetStdHandle(STD_INPUT_HANDLE)
    self.readHandle.SetConsoleMode(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT)



  def startReading(self, readCallback):
    self.stopLock.acquire()

    try:
      if not self.stopped:
        raise Exception(&quot;Capture is already going&quot;)

      self.stopped = False
      self.readCallback = readCallback

      backgroundCaptureThread = threading.Thread(target=self.backgroundThreadReading)
      backgroundCaptureThread.daemon = True
      backgroundCaptureThread.start()
    except:
      self.stopLock.release()
      raise

    self.stopLock.release()


  def backgroundThreadReading(self):
    curEventLength = 0
    curKeysLength = 0
    while True:
      eventsPeek = self.readHandle.PeekConsoleInput(10000)

      self.stopLock.acquire()
      if self.stopped:
        self.stopLock.release()
        return
      self.stopLock.release()


      if len(eventsPeek) == 0:
        continue

      if not len(eventsPeek) == curEventLength:
        if self.getCharsFromEvents(eventsPeek[curEventLength:]):
          self.stopLock.acquire()
          self.stopped = True
          self.stopLock.release()
          break

        curEventLength = len(eventsPeek)



  def getCharsFromEvents(self, eventsPeek):
    callbackReturnedTrue = False
    for curEvent in eventsPeek:
      if curEvent.EventType == KEY_EVENT:
              if ord(curEvent.Char) == 0 or not curEvent.KeyDown:
                pass
              else:
                curChar = str(curEvent.Char)
                if self.readCallback(curChar) == True:
                  callbackReturnedTrue = True


    return callbackReturnedTrue

  def stopReading(self):
    self.stopLock.acquire()
    self.stopped = True
    self.stopLock.release()</code>
Nach dem Login kopieren

Abfrage:

Der Benutzer möchte einfach in der Lage sein, etwas zu tun, wenn eine Taste gedrückt wird, ohne auf diese Taste warten zu müssen (dies sollte also nicht blockierend sein) . Daher rufen sie eine poll()-Funktion auf, die entweder einen Schlüssel oder None zurückgibt. Dies kann entweder verlustbehaftet sein (wenn es zwischen den Abfragen zu lange dauert, eine Taste zu übersehen) oder nicht verlustbehaftet (der Poller speichert den Verlauf aller gedrückten Tasten, sodass diese immer zurückgegeben werden, wenn die Funktion poll() sie anfordert). in der gedrückten Reihenfolge).

Windows und OS X (und möglicherweise Linux):

<code class="python">global isWindows

isWindows = False
try:
  from win32api import STD_INPUT_HANDLE
  from win32console import GetStdHandle, KEY_EVENT, ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT
  isWindows = True
except ImportError as e:
  import sys
  import select
  import termios


class KeyPoller():
  def __enter__(self):
    global isWindows
    if isWindows:
      self.readHandle = GetStdHandle(STD_INPUT_HANDLE)
      self.readHandle.SetConsoleMode(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT)
      
      self.curEventLength = 0
      self.curKeysLength = 0
      
      self.capturedChars = []
    else:
      # Save the terminal settings
      self.fd = sys.stdin.fileno()
      self.new_term = termios.tcgetattr(self.fd)
      self.old_term = termios.tcgetattr(self.fd)
      
      # New terminal setting unbuffered
      self.new_term[3] = (self.new_term[3] &amp; ~termios.ICANON &amp; ~termios.ECHO)
      termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term)
      
    return self
  
  def __exit__(self, type, value, traceback):
    if isWindows:
      pass
    else:
      termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term)
  
  def poll(self):
    if isWindows:
      if not len(self.capturedChars) == 0:
        return self.capturedChars.pop(0)

      eventsPeek = self.readHandle.PeekConsoleInput(10000)
</code>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie erkenne ich Tastatureingaben in einem Python-Skript, das vom Terminal aus ausgeführt wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage