2008-11-15 20 views
56

में कुंजीपटल मतदान (कुंजीपटल का पता लगाएं) मैं कंसोल पायथन ऐप से कीबोर्ड कैसे मतदान कर सकता हूं?पाइथन

while 1: 
     # doing amazing pythonic embedded stuff 
     # ... 

     # periodically do a non-blocking check to see if 
     # we are being told to do something else 
     x = keyboard.read(1000, timeout = 0) 

     if len(x): 
      # ok, some key got pressed 
      # do something 

क्या करना है सही pythonic तरीका है: विशेष रूप से, मैं अन्य आई/ओ गतिविधियों (सॉकेट चयन, सीरियल पोर्ट का उपयोग, आदि) का एक बहुत के बीच में इस के लिए कुछ सदृश करना चाहते हैं विंडोज़ पर यह? इसके अलावा, लिनक्स के लिए पोर्टेबिलिटी खराब नहीं होगी, हालांकि इसकी आवश्यकता नहीं है।

+0

बस अन्य लोगों को यह बताने के लिए, मैंने पाया कि सबसे का चयन करें या धागा पुस्तकालयों को शामिल समाधान निष्क्रिय से सही ढंग से काम नहीं किया। हालांकि, वे _ ** सभी ** _ ने सीएलआई पर ठीक काम किया है। 'पायथन/होम/पीआई/poll_keyboard.py' – davidhood2

उत्तर

26

मानक दृष्टिकोण select मॉड्यूल का उपयोग करना है।

हालांकि, यह विंडोज पर काम नहीं करता है। इसके लिए, आप msvcrt मॉड्यूल के कीबोर्ड मतदान का उपयोग कर सकते हैं।

अक्सर, यह एकाधिक धागे के साथ किया जाता है - प्रति डिवाइस एक "देखा" और पृष्ठभूमि प्रक्रियाओं को डिवाइस द्वारा बाधित करने की आवश्यकता हो सकती है।

6

आप देख सकते हैं कि pygame कुछ विचारों को चुरा लेने के लिए इसे कैसे संभालता है।

5
टिप्पणियों से

:

import msvcrt # built-in module 

def kbfunc(): 
    return ord(msvcrt.getch()) if msvcrt.kbhit() else 0 

मदद के लिए धन्यवाद। मैं एक सी DLL PyKeyboardAccess.dll बुलाया लेखन और CRT conio कार्यों तक पहुँचने, निर्यात समाप्त हो गया इस दिनचर्या:

import ctypes 
import time 

# 
# first, load the DLL 
# 


try: 
    kblib = ctypes.CDLL("PyKeyboardAccess.dll") 
except: 
    raise ("Error Loading PyKeyboardAccess.dll") 


# 
# now, find our function 
# 

try: 
    kbfunc = kblib.kb_inkey 
except: 
    raise ("Could not find the kb_inkey function in the dll!") 


# 
# Ok, now let's demo the capability 
# 

while 1: 
    x = kbfunc() 

    if x != 0: 
     print "Got key: %d" % x 
    else: 
     time.sleep(.01) 
:

#include <conio.h> 

int kb_inkey() { 
    int rc; 
    int key; 

    key = _kbhit(); 

    if (key == 0) { 
     rc = 0; 
    } else { 
     rc = _getch(); 
    } 

    return rc; 
} 

और मैं ctypes मॉड्यूल का उपयोग कर अजगर में इसे उपयोग (अजगर 2.5 में निर्मित)

+0

बिल्ट-इन msvcrt.kbhit() से बेहतर कैसे है? इसका क्या फायदा है? –

+0

आप बिल्कुल सही हैं! मैंने आपकी पोस्ट को गलत तरीके से पढ़ाया; मुझे एहसास नहीं हुआ कि एक पाइथन मॉड्यूल है जिसे msvcrt कहा जाता है! मैंने सोचा कि आपका मतलब है "एमएस सीआरटी का उपयोग करें," और फिर मैं धागे के बारे में सोचने के लिए तैयार हो गया और डॉट्स को कनेक्ट नहीं किया। तुम पूरी तरह ठीक हो। आयात MSVCRT डीईएफ़ kbfunc(): –

+1

मैं के साथ ऐसा ही किया था एक्स = msvcrt.kbhit() अगर एक्स: सेवानिवृत्त = ord (msvcrt.getch()) और : सेवानिवृत्त = 0 वापसी –

14

ठीक है, क्योंकि एक टिप्पणी में मेरा समाधान पोस्ट करने का मेरा प्रयास असफल रहा, मैं यही कहने की कोशिश कर रहा था। मैं निम्नलिखित कोड के साथ वास्तव में क्या मैं (नहीं कहीं और है, हालांकि विंडोज पर,) देशी अजगर से चाहता था कर सकता है:

import msvcrt 

def kbfunc(): 
    x = msvcrt.kbhit() 
    if x: 
     ret = ord(msvcrt.getch()) 
    else: 
     ret = 0 
    return ret 
16

import sys 
import select 

def heardEnter(): 
    i,o,e = select.select([sys.stdin],[],[],0.0001) 
    for s in i: 
     if s == sys.stdin: 
      input = sys.stdin.readline() 
      return True 
    return False 
+0

कोई काम नहीं। त्रुटि मिली: select.error: (100 9 3, 'या तो एप्लिकेशन ने WSAStartup, या WSAStartup को विफल नहीं किया है') – DarenW

+1

मैंने सुना है, कुछ बार से अधिक, कि एमएस विंडोज़ पर चयन सिस्टम कॉल नियमित फ़ाइल का समर्थन नहीं करता है वर्णनकर्ता और केवल सॉकेट पर काम करता है। (मुझे नहीं पता कि चुनिंदा() के पाइथन कार्यान्वयन ने कभी भी हुड के नीचे काम किया है या नहीं। –

+0

इस अजीब टाइमआउट के लिए क्या है? यह मेरे लिए टाइमआउट = 0 के साथ काम करता है लेकिन दिखाए गए 0.0001 के साथ नहीं .. – frans

13

एक समाधान शाप मॉड्यूल का उपयोग कर। मुद्रण एक अंकीय मान प्रत्येक कुंजी के लिए इसी दबाया:

import curses 

def main(stdscr): 
    # do not wait for input when calling getch 
    stdscr.nodelay(1) 
    while True: 
     # get keyboard input, returns -1 if none available 
     c = stdscr.getch() 
     if c != -1: 
      # print numeric value 
      stdscr.addstr(str(c) + ' ') 
      stdscr.refresh() 
      # return curser to start position 
      stdscr.move(0, 0) 

if __name__ == '__main__': 
    curses.wrapper(main) 
+1

यह विंडोज़ पर काम नहीं करता है ... – Oz123

+0

OZ123: यह कर सकता है। Http://stackoverflow.com/questions/32417379/what-is-needed-for-curses-in-python-3-4-on-windows7 –

+0

हेडलेस होस्ट पर एसएसएच टर्म के माध्यम से शाप का उपयोग करने में समस्याएं थीं। समस्याएं टर्मिनल को बुरी तरह खराब कर रही थीं - इसे प्रत्येक रन के बीच 'रीसेट' करने की आवश्यकता होती है। यह काम किया, यानी कुंजीपटल का पता लगाने। एक बेहतर समाधान होना चाहिए। – Mark

0

आप time.sleep, threading.Thread गठबंधन, और sys.stdin.read आप आसानी से निवेश के लिए समय की एक निर्दिष्ट राशि के लिए प्रतीक्षा करें और फिर जारी रखने के लिए कर सकते हैं, यह भी क्रॉस-प्लेटफॉर्म संगत होना चाहिए।

t = threading.Thread(target=sys.stdin.read(1) args=(1,)) 
t.start() 
time.sleep(5) 
t.join() 

तुम भी तो

def timed_getch(self, bytes=1, timeout=1): 
    t = threading.Thread(target=sys.stdin.read, args=(bytes,)) 
    t.start() 
    time.sleep(timeout) 
    t.join() 
    del t 

की तरह एक समारोह में इस जगह सकता है इस कुछ भी वापस नहीं होगा हालांकि इतना बजाय आप बहु पूल मॉड्यूल का उपयोग करना चाहिए आपको लगता है कि यहाँ पा सकते हैं: how to get the return value from a thread in python?

+0

यह पहली पंक्ति नहीं होनी चाहिए: टी = थ्रेडिंग। थ्रेड (target = sys.stdin.read, args = (1,)) –

+0

क्या यह समाधान हमेशा 5 सेकंड तक सो नहीं जाएगा, भले ही उपयोगकर्ता पहले एक कुंजी दबाए उस? –

7

इनमें से कोई भी जवाब मेरे लिए अच्छा काम नहीं करता है। यह पैकेज, पिनपुट, वही करता है जो मुझे चाहिए।

https://pypi.python.org/pypi/pynput

from pynput.keyboard import Key, Listener 

def on_press(key): 
    print('{0} pressed'.format(
     key)) 

def on_release(key): 
    print('{0} release'.format(
     key)) 
    if key == Key.esc: 
     # Stop listener 
     return False 

# Collect events until released 
with Listener(
     on_press=on_press, 
     on_release=on_release) as listener: 
    listener.join() 
+0

यह मेरे लिए काम करता है, दबाए जाने के तुरंत बाद स्क्रीन पर दबाए गए कुंजी को प्रतिबिंबित करने के तुरंत बाद स्क्रीन पर प्रतिबिंबित किया गया था, और इसे अक्षम करने का कोई तरीका नहीं था। https://github.com/moses-palmer/pynput/issues/47 प्लस, वर्णों को buffered और अतिरिक्त रूप से कमांड लाइन पर दिखाई देता है जब प्रोग्राम भी बाहर निकलता है। यह लिनक्स कार्यान्वयन की एक सीमा है , लेकिन यह विंडोज पर ठीक काम करता है। – Trevor

+0

स्क्रिप्ट के माध्यम से स्क्रिप्ट चलाते समय यह समाधान काम नहीं करता है। यह त्रुटि के साथ बाहर निकलता है: 'Xlib.error.DisplayNameError: खराब प्रदर्शन नाम ""। –

+0

जैसा कि उपरोक्त उल्लेख किया गया है - यह हेडलेस उदाहरणों के लिए एक अच्छा समाधान नहीं है क्योंकि इसकी Xserver पर निर्भरता है। 'Xlib.display आयात करें' – Mark

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^