私はスレッドクラスを持っていて、私のメイン関数で何度もスレッドを開始/停止したいと思っています。私はthis linkとthis methodを使って私の問題を解決しました。ここでは、コンソールでキーストロークを出力する簡単なスレッドである:私はときthr.stop()
を呼び出し、それがwhileループ終了し、いくつかのキーストロークを押ししようとすると、スレッドがすでに停止しているようですが、ときPythonでスレッディングするループを制御する
global isWindows
isWindows = False
try:
from win32api import STD_INPUT_HANDLE
from win32console import GetStdHandle, KEY_EVENT, ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT
import win32gui
import threading
from time import sleep
import sys
isWindows = True
except ImportError as e:
import sys
import select
import termios
class KeyPoller(threading.Thread):
def __init__(self):
super(KeyPoller, self).__init__()
#threading.Thread.__init__(self)
self.stop_event = threading.Event()
global isWindows
if isWindows:
self.readHandle = GetStdHandle(STD_INPUT_HANDLE)
self.readHandle.SetConsoleMode(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT)
self.curEventLength = 0
self.curKeysLength = 0
self.capturedChars = []
else:
# Save the terminal settings
self.fd = sys.stdin.fileno()
self.new_term = termios.tcgetattr(self.fd)
self.old_term = termios.tcgetattr(self.fd)
# New terminal setting unbuffered
self.new_term[3] = (self.new_term[3] & ~termios.ICANON & ~termios.ECHO)
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term)
def poll(self):
if isWindows:
if not len(self.capturedChars) == 0:
return self.capturedChars.pop(0)
eventsPeek = self.readHandle.PeekConsoleInput(10000)
if len(eventsPeek) == 0:
return None
if not len(eventsPeek) == self.curEventLength:
for curEvent in eventsPeek[self.curEventLength:]:
if curEvent.EventType == KEY_EVENT:
if ord(curEvent.Char) == 0 or not curEvent.KeyDown:
pass
else:
curChar = str(curEvent.Char)
self.capturedChars.append(curChar)
self.curEventLength = len(eventsPeek)
if not len(self.capturedChars) == 0:
return self.capturedChars.pop(0)
else:
return None
else:
dr,dw,de = select.select([sys.stdin], [], [], 0)
if not dr == []:
return sys.stdin.read(1)
return None
def stop(self):
print("stopping the thread")
self.stop_event.set()
def stopped(self):
return self.stop_event.is_set()
def run(self):
while not self.stopped():
c=self.poll()
if not c is None:
print(c)
if __name__=='__main__':
thr=KeyPoller()
print("starting the thread #1")
thr.start()
sleep(5)
print("stopping the thread #1")
# sadly if you press any key in this time it would be saved and printed after thr2.start
thr.stop()
thr.join()
sleep(5)
thr2=KeyPoller()
print("starting the thread #2")
thr2.start()
sleep(5)
print("stopping the thread #2")
thr2.stop()
print("Exiting the whole program")
私の問題はあるがI thr2.start()
を呼び出すと、私のスレッドの最初のインスタンスから古いキーストロークが表示され、停止機能を呼び出すかどうかに関わらず、すべてのキーストロークがまだ残っているようです。
チップをありがとう、私は窓を使用していますが、私は同じ問題に直面しています。 –
あなたの答えはうまくいきませんでしたが、私は単純な関数で置き換えようとしました。ありがとう。 –