我试图实现的是一个超时倒数,可以通过pynput
键事件来中断。
在我的第一个实现中,有一个错误:我看不到告诉Pynput线程超时已结束的可能性。
根据Python threading文档,我需要创建一个更复杂的 Condition 对象,还是某种同步线程?还是我想扩展原始的Pynput类?
对于我来说,在这种情况下很难理解哪个线程是生产者还是消费者。
代码。
模块代码
import threading
import time
from pynput import keyboard
import subprocess
class CountdownWithInterrupt:
"""A countdown feature which user can interrupt by pressing Enter key"""
def __init__(self, interval, message="Press enter to continue..."):
"""Constructor"""
self.window_id = self.obtain_window_id()
self.interrupt_key = keyboard.Key.enter
self.message = message
self.user_pressed_key = False
self.timeout_over = False
self.timer_thread = threading.Thread(name='timer',
target=self.timer,
kwargs={"interval":interval})
self.kblistener_thread = threading.Thread(name='keyboard_listener',
target=self.keyboard_listener)
def obtain_window_id(self):
"""Ignore keyboard events if they come from other windows"""
try:
result = subprocess.run(['xdotool', 'getactivewindow'], stdout=subprocess.PIPE)
window_id = result.stdout
except DisplayNameError:
window_id = print (random.randint(1,21)*5)
return window_id
def lock(self):
return self.user_pressed_key or self.timeout_over
def start(self):
"""starts countdown"""
print(self.message)
self.timer_thread.start()
self.kblistener_thread.start()
def on_release(self, key):
"""listener action"""
if (self.window_id != self.obtain_window_id()):
return True
if key == self.interrupt_key:
# Stop listener
self.user_pressed_key = True
return False
return True
def keyboard_listener(self):
"""listen for interrupt"""
with keyboard.Listener(on_release=self.on_release) as listener:
listener.join()
def timer(self, interval):
"""set up the resource to be used by the consumer"""
time_left = interval
while time_left > 0:
if self.user_pressed_key:
break
print(time_left, end='\r', flush=True)
time.sleep(1)
time_left = time_left - 1
self.timeout_over = True
实际程序
from modules.helpers import CountdownWithInterrupt
msg = ("Press enter..")
interruptableCountdown = CountdownWithInterrupt(5, msg)
interruptableCountdown.start()
while(interruptableCountdown.lock() == False):
pass
print("tuut!")
答案 0 :(得分:0)
与listener.stop()
为我工作。