0

我目前正試圖通過按一個鍵(start)和通過釋放鍵來停止while循環。在while循環之外更改條件變量的狀態for while while循環

因此,像這樣:

from pynput import keyboard 
global condition 
condition = False 

def on_press(key): 
    global condition 
    if key == keyboard.Key.cmd_r: 
     print('pressed cmd_r'.format(key)) 
     condition = True 
    else: 
     print('incorrect character {0}, press cmd_r'.format(key)) 


def on_release(key): 
    global condition 
    print('{0} released'.format(key)) 
    if key == keyboard.Key.cmd_r: 
     condition = False 
     #keyboard.Listener.stop 
     #return False 


with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: 
    listener.join() 

while condition==True: 
    print "Condition true" 

我不知道這是爲什麼不工作.. 它應該在我的頭上?

+0

它可能是條件在開始時是False,所以它實際上從不啓動while循環並且進程結束? –

+0

也'應該在回調中聲明'全局' –

+0

我已經在頂部設置了'global',但是它也應該在回調中完成嗎? – jkn

回答

0

的問題是,當你調用listener.join()您的代碼等待在這一點上的線程來完成。但它永遠不會完成,因爲它總是在傾聽!相反,您想調用listener.start(),以便線程在後臺運行,並且可以自由地按照自己的意願進行操作。

在線程之間共享變量通常不被接受,所以在這裏我創建了一個修改的偵聽器類,它在按下按鍵時將變量key_pressed關聯到自身,並在發佈時關聯None。然後,您可以通過調用listener.key_pressed

from pynput import keyboard 
import time 


class MyListener(keyboard.Listener): 
    def __init__(self): 
     super(MyListener, self).__init__(self.on_press, self.on_release) 
     self.key_pressed = None 

    def on_press(self, key): 
     self.key_pressed = key 

    def on_release(self, key): 
     self.key_pressed = None 


listener = MyListener() 
listener.start() 

while True: 
    time.sleep(0.1) 
    print listener.key_pressed 

需要注意的是,如果你不包括與上面time.sleep的延遲,你會超載緩衝區你想利用這個變量,什麼通過在一個單獨的迴路隨時檢查它並導致產出延遲。如果你想要快速,只需要一點點延遲,但不能爲零。

+0

另外爲了確保您能夠捕捉按鍵事件,您可能需要將'on_release'方法修改爲具有'self.key_pressed = key'。但是,這使得聽衆在一次按鍵事件後無用,但也許這就是你想要的! – henneray

+0

這看起來像我正在尋找的東西,'on_release'必須停止行動,所以重置爲'None'應該是正確的..說應該,因爲我似乎有一些問題實現功能.. – jkn

+0

這將聽起來很愚蠢,但如何檢查按鍵是否被按下? 我似乎無法測試變量「listener.key_pressed」與任何鍵打印出來,除了沒有? – jkn

0

您可能需要類似主循環的地方,您可以在其中包含特殊的while循環來實現此目的。

更新1 - 如何? (錯誤的)

while True: 
    # main loop 
    while condition: 
     # your special loop 
     # do something... 
    time.sleep(0.1) # sleep 0.1 seconds 

「主循環」是一個無限循環和執行包括指令每0.1秒。因此,您可以繼續檢查condition。如果condition == True你的「特殊循環」要執行,並且它在condition == False,然後「主循環」繼續執行時停止。

更新2 - 執行(正確的)

好吧,我運行代碼,我看到「主循環」的解決方案是不是在這裏。現在,我已經快,測試解決方案,基於多線程:

import time 
import threading 

from pynput import keyboard 


condition = False 


def my_special_task(): 
    global condition 
    while condition: 
     print("condition = %s" % condition) 
     time.sleep(0.1) 


def on_press(key): 
    global condition 
    if key == keyboard.Key.ctrl_r: 
     print('Pressed ctrl_r') 
     condition = True 
     thread = threading.Thread(target=my_special_task) 
     thread.start() 
    else: 
     print("Incorrect KEY: %s, press ctrl_r instead" % key) 


def on_release(key): 
    global condition 
    print("%s released" % key) 
    if key == keyboard.Key.ctrl_r: 
     condition = False 


with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: 
    listener.join() 
+0

但是如何?...我真的不知道它應該如何? – jkn

+0

以及你如何從鍵盤讀取輸入,或者改變while循環的條件? – jkn

+0

我承認「主循環」解決方案是錯誤的,但我找到了正確的解決方案並更新了答案。對不起,誤導。我認爲它需要Python中的一些多線程知識來理解和解決像這樣的問題。 –