2011-03-29 8 views
10

मुझे वर्तमान में किसी प्रोग्राम के लिए एकाधिक कीबोर्ड इंटरप्ट प्रदान करने की आवश्यकता है। सिग्नल क्लास के साथ ऐसा करने का कोई आसान तरीका है? मैं वर्तमान में SIGINT/Ctrl+C का उपयोग करता हूं लेकिन मुझे कोई अन्य कीबोर्ड मैपिंग नहीं मिल रहा है।पायथन: अंतर्निहित कीबोर्ड सिग्नल/इंटरप्ट्स

2 से अधिक संकेतों के लिए अच्छा होगा। मैं या तो अधिक संकेतों को परिभाषित कैसे कर सकता हूं या "किसी उपयोगकर्ता से बाधा" को कैप्चर करने का एक बेहतर तरीका है?

def shutdown(signal, frame): 
     if(signal==2): #sigint 
      print 'do something' 
     elif signal==XX: 
      print 'do something else' 
     # continued... 

signal.signal(signal.SIGINT, shutdown) 
signal.signal(signal.SOMEOTHERTYPE, shutdown) 


print 'start' 
t = Thread(target=run) 
t.setDaemon(True) 
t.start() 

print 'Done, press ctrl c, or ctrl ? ' 
signal.pause() 
+0

'2' हमेशा सत्य है। – delnan

+0

किस मंच पर? विंडोज़ पर सिग्नल सपोर्ट में बहुत सारे सिग्नल गायब हैं ... –

+0

इसकी टैग की गईं, लिनक्स। – Nix

उत्तर

11

Ctrl+\ का उल्लेख किया गया है जो आपके टर्मिनल सॉफ़्टवेयर द्वारा व्याख्या किया गया है, और कुंजी बाइंडिंग stty के माध्यम से कॉन्फ़िगर किया गया है। जब तक कि आपके टर्मिनल सॉफ़्टवेयर को कस्टमाइज़ करने का कोई तरीका न हो, आप केवल कुछ सिग्नल का उपयोग कर सकेंगे जो पहले से ही बनाए गए हैं।

इस पर निर्भर करता है कि आपको कितनी कार्यक्षमता चाहिए या आप इसे कितना लेना चाहते हैं, दूसरा विकल्प है अपना खुद का सरल "प्रक्रिया निष्पादन टर्मिनल" लिखने के लिए। यह एक ऐसी स्क्रिप्ट होगी जो आपके लिए एक ऐप निष्पादित करेगी और आपके टर्मिनल को कच्चे मोड में रखेगी ताकि वह कीस्ट्रोक को संसाधित कर सके जो कस्टम क्रियाएं करता है।

नीचे एक विस्तृत उदाहरण है जो दिखा रहा है कि मेरा क्या मतलब है। यदि आप चाहें तो curses या urwid के माध्यम से आप कुछ भी ऐसा कर सकते हैं।

प्रक्रिया उत्पादन को संभालने के लिए आप की stdout/stderr पर कब्जा और स्क्रीन के लिए अच्छी तरह से यह प्रदर्शित करते हैं, का उपयोग कर यदि आप आदि मैन्युअल टर्मिनल से छेड़छाड़, या एक स्क्रॉल विंडो में उत्पादन प्रदर्शित करने के लिए एक urwid विजेट का उपयोग कर रहे हैं, नहीं करनी होंगी एक ही विचार अन्य जीयूआई सिस्टम (डब्ल्यूएक्स, टिंकर, आदि) तक भी विस्तारित होगा लेकिन टर्मिनल नियंत्रण का उल्लेख किया गया था।

import signal, sys, time 

def handler(num, _): 
    print 'got:', sigmap.get(num, '<other>') 
    if num == signal.SIGINT: 
     sys.exit(1) 
    return 1 

signames = ['SIGINT','SIGHUP','SIGQUIT','SIGUSR1'] 
sigmap = dict((getattr(signal, k), k) for k in signames) 
for name in signames: 
    signal.signal(getattr(signal, name), handler) 
while 1: 
    time.sleep(1) 

प्रयोग उदाहरण:

import os, signal, subprocess, sys, tty, termios 

sigmap = { 
    '\x15': signal.SIGUSR1,  # ctrl-u 
    '\x1c': signal.SIGQUIT,  # ctrl-\ 
    '\x08': signal.SIGHUP,  # ctrl-h 
    '\x09': signal.SIGINT,  # ctrl-i 
    } 
# setup tty 
fd = sys.stdin.fileno() 
old_tc = termios.tcgetattr(fd) 
tty.setraw(fd) 
# spawn command as a child proc 
cmd = sys.argv[1:] 
proc = subprocess.Popen(cmd) 
while 1: 
    try: 
     ch = sys.stdin.read(1) 
     # example of ansi escape to move cursor down and to column 0 
     print '\033[1Eyou entered', repr(ch) 
     if ch == 'q': 
      break 
     signum = sigmap.get(ch) 
     if signum: 
      os.kill(proc.pid, signum) 
    finally: 
     pass 
termios.tcsetattr(fd, termios.TCSANOW, old_tc) 
sys.exit() 

यहाँ एक सरल target.py स्पिन और संकेत यह प्राप्त करता है मुद्रित करने के लिए स्क्रिप्ट है:

यहाँ term.py जो एक बुनियादी कच्चे टर्मिनल दुभाषिया लागू करता है

% python term.py python target.py 
you entered 'h' 
you entered 'i' 
you entered '\x1c' 
        got: SIGQUIT 
you entered '\x15' 
        got: SIGUSR1 
you entered '\x08' 
        got: SIGHUP 
you entered '\t' 
       got: SIGINT 
you entered 'q' 
5

Linux सिस्टम पर, Ctrl + \ एक signal.SIGQUIT संकेत उत्पन्न करेगा:

यहाँ वर्तमान कोड का एक highlevel दृश्य है।

+1

क्या नए लोगों को परिभाषित करने का कोई तरीका है? या ज्यादा? – Nix

0

मुझे यकीन नहीं है कि नए सिग्नल को परिभाषित करने और उन्हें कीबोर्ड ईवेंट में मैप करने का एक प्रीमिस्ड तरीका है या नहीं।

यदि आपको उस तरह की लचीलापन की आवश्यकता है, तो आपको एक इंटरफ़ेस थ्रेड का उपयोग करना पड़ सकता है जो अग्रभूमि में रहता है और कीबोर्ड ईवेंट के लिए सुनता है। इसके बाद यह किसी अन्य तरीके से अन्य धागे के साथ संवाद कर सकता है।

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