前回の記事では、Python プログラムが Windows システムでキーボード入力を監視する 2 つの方法、つまり、keyboard と pynput ツールキットを紹介しましたが、どちらの方法でも、Linux サーバーをリモートで制御するときに問題が発生します。 Python: Windows システムでの監視 キーボード入力の 2 つの
方法
この記事では、プログラム実行中のキーボード入力監視を実現するために、新しいスレッドを開いてイベントを監視する方法を紹介します.この方法は、Linuxサーバーをリモートで制御する場合にも通常どおり使用できます.
まず、スレッドの終了をアクティブに制御できるスレッドを定義するには、スレッド化で Thread クラスを継承し、その _stop メソッドを書き直す必要があります。
import threading
class StoppableThread(threading.Thread):
"""
a stoppable thread, inherit from threading.Thread
"""
def __init__(self, target):
super(StoppableThread, self).__init__(target=target)
def _stop(self):
"""
stop the thread, overwrite method, modified from threading.py
:return:
"""
lock = self._tstate_lock
self._is_stopped = True
self._tstate_lock = None
if not self.daemon:
with threading._shutdown_locks_lock:
threading._shutdown_locks.discard(lock)
ここで、Python のバージョンは 3.7 以降であることに注意してください。Python 3.6 を使用すると、スレッド モジュールに _shutdown_locks_lock 属性がないというエラーが報告されます。
イベントを定義し、イベントに従ってスレッドのターゲット関数を記述します。
# event
event_flag = threading.Event()
event_flag.set()
def thread_target():
"""
thread target function, inspect event flag
:return:
"""
global event_flag
while True:
if event_flag.is_set():
input("Press <enter> to pause:")
event_flag.clear()
event_flag.wait()
効果を確認するために、メイン スレッドは for ループを介してタイミングを計り、新しいスレッドはキーボード入力を監視します。
import time
if __name__ == '__main__':
# thread
thread = StoppableThread(target=thread_target)
thread.start()
tms = time.time()
for i in range(100):
print(i)
time.sleep(0.1)
if not event_flag.is_set():
s = input("Please input something:")
print("You input {}".format(s))
event_flag.set()
tme = time.time()
tm = round(tme - tms, 3)
print()
print("for loop running time: {} s".format(tm))
thread._stop()