2011-03-29 109 views
10

我目前需要爲一個程序提供多個鍵盤中斷。有沒有簡單的方法來做到這一點與信號類?我目前使用SIGINT/Ctrl+C,但我找不到任何其他鍵盤映射。Python:內置鍵盤信號/中斷

會有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 2011-03-29 16:06:32

+0

在哪個平臺上?在Windows上支持信號丟失大量的信號... – 2011-03-29 18:37:33

+0

它的標記,Linux操作系統。 – Nix 2011-03-29 20:19:57

回答

11

已經提到的Ctrl+\通過終端軟件解釋,關鍵綁定是通過stty配置。除非你有一些定製你的終端軟件的方法,否則你只能使用已經內置的少量信號。

根據你需要多少功能或需要多遠,另一個選擇是編寫你自己的簡單的「流程執行終端」。這將是一個爲您執行應用程序並將您的終端置於原始模式的腳本,以便它可以處理執行自定義操作的擊鍵。

下面是一個過於簡單的例子,顯示我的意思。如果你喜歡,你也可以通過cursesurwid做類似的事情。

要處理過程輸出你需要捕獲的stdout/stderr並很好地顯示它到屏幕上,使用如果要手動操縱終端,或使用urwid插件來顯示在滾動窗口的輸出等。同樣的想法也會擴展到其他GUI系統(wx,tkinter等),但提到了終端控制。

這裏是term.py它實現了一個基本原料終端解釋:

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腳本旋轉並打印接收到的信號:

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) 

用例:

% 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信號。

+1

有沒有一種方法來定義新的?或者更多? – Nix 2011-05-25 14:29:22

0

我不確定是否有預先定義的方式來定義新信號並將它們映射到鍵盤事件。

如果您需要這種靈活性,您可能必須使用保留在前臺的接口線程並監聽鍵盤事件。然後它可以用任何你喜歡的方式與其他線程進行通信。