使用 Pynput 按键暂停和取消暂停 TQDM 进度条
Pause and Unpause TQDM Progress Bar Using Pynput Key Press
我正在创建一个使用 TQDM 进度条库的小程序,我想在其中按 space 来“暂停”和“取消暂停”进度条。进度条应该每秒更新一次,当输入的时间完成时 运行 100%。请查看我在下面所做的尝试,当 运行 时,进度条永远不会自行更新。感谢您的反馈。
from tqdm import tqdm
from pynput import keyboard
class TimerTimer:
def __init__(self, fileLoc) -> None:
self.timer_list = self.get_timer_list(fileLoc)
self.timer_length = len(self.timer_list)
self.kb_listener = None
self.init_val = 0
self.wait = False
def on_press_or_release(self, key):
if key == keyboard.Key.esc:
print("Exiting")
exit()
if key == keyboard.Key.space:
self.wait = not self.wait
printStr = "\nPaused...\n" if self.wait else "\nResumed!"
print(printStr)
return False
def timer_with_progress(self, time_limit, name):
print("{} for {} seconds:".format(name, time_limit))
t = tqdm(total=time_limit, desc=name, ncols=100, initial=self.init_val)
#for i in tqdm(range(time_limit), desc=name, ncols=100, initial=self.init_val):
for i in range(time_limit):
# sleep(1)
# The event listener will be running in this block
with keyboard.Events() as events:
# Block at most one second
event = events.get(1.0)
if event is None:
break
elif event.key == keyboard.Key.esc:
print("Exiting")
exit()
elif event.key == keyboard.Key.space:
self.wait = not self.wait
printStr = "\nPaused...\n" if self.wait else "\nResumed!"
print(printStr)
else:
break
t.update()
# t.refresh()
t.close()
def run(self):
for index in self.timer_list:
timer_cmd_list = ["self.timer_with_progress(5, 'Rest')",
"self.timer_with_progress(self.timer_list[index]['durationSeconds'], self.timer_list[index]['timerName'])"]
for cmd in timer_cmd_list:
if not self.wait:
exec(cmd)
else:
if self.kb_listener is None:
self.kb_listener = keyboard.Listener(on_press = self.on_press_or_release) # , on_release = self.on_press_or_release)
self.kb_listener.start()
self.kb_listener.join() # Waits until the key is pressed again
self.wait = not self.wait # Once the button is pressed again, it changes the flag
if __name__=="__main__":
tt = TimerTimer(filename)
tt.run()
所以经过一些研究,我发现 progressbar2 似乎实现了一个更好的中断来完成我的目标。见下文:
import progressbar
from pynput import keyboard
from time import sleep
class TimerTimer:
def __init__(self, fileLoc) -> None:
self.timer_list = self.get_timer_list(fileLoc)
self.timer_length = len(self.timer_list)
self.wait = False
def on_press(self, key):
pass
def on_release(self, key):
if key == keyboard.Key.space:
self.wait = not self.wait
printStr = "Paused..." if self.wait else "\nResuming..."
print(printStr)
elif key == keyboard.Key.esc:
print("Exiting")
exit()
def timer_with_progress(self, time_limit: int, name: str, iter:int=1) -> None:
"""Function that runs the progressbar2 progress bar.
Keyword arguments:
time_limit -- (int) The time limit (in seconds) for the progress bar.
name -- (string) The Name of the progress bar, or the brief description.
iter -- (int) The iteration time in seconds. (default 1)
"""
print("{} for {} seconds:".format(color.BOLD + name +color.END, time_limit))
bar = progressbar.ProgressBar(max_value=time_limit)
i = 0
# Adding keyboard listener
listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
listener.start()
while i <= time_limit:
sleep(iter)
if not self.wait:
bar.update(i)
i += iter
bar.finish()
def run(self):
for index in self.timer_list:
self.timer_with_progress(5, 'Rest')
self.timer_with_progress(self.timer_list[index]['durationSeconds'], self.timer_list[index]['timerName'])
if __name__=="__main__":
tt = TimerTimer(filename)
tt.run()
我正在创建一个使用 TQDM 进度条库的小程序,我想在其中按 space 来“暂停”和“取消暂停”进度条。进度条应该每秒更新一次,当输入的时间完成时 运行 100%。请查看我在下面所做的尝试,当 运行 时,进度条永远不会自行更新。感谢您的反馈。
from tqdm import tqdm
from pynput import keyboard
class TimerTimer:
def __init__(self, fileLoc) -> None:
self.timer_list = self.get_timer_list(fileLoc)
self.timer_length = len(self.timer_list)
self.kb_listener = None
self.init_val = 0
self.wait = False
def on_press_or_release(self, key):
if key == keyboard.Key.esc:
print("Exiting")
exit()
if key == keyboard.Key.space:
self.wait = not self.wait
printStr = "\nPaused...\n" if self.wait else "\nResumed!"
print(printStr)
return False
def timer_with_progress(self, time_limit, name):
print("{} for {} seconds:".format(name, time_limit))
t = tqdm(total=time_limit, desc=name, ncols=100, initial=self.init_val)
#for i in tqdm(range(time_limit), desc=name, ncols=100, initial=self.init_val):
for i in range(time_limit):
# sleep(1)
# The event listener will be running in this block
with keyboard.Events() as events:
# Block at most one second
event = events.get(1.0)
if event is None:
break
elif event.key == keyboard.Key.esc:
print("Exiting")
exit()
elif event.key == keyboard.Key.space:
self.wait = not self.wait
printStr = "\nPaused...\n" if self.wait else "\nResumed!"
print(printStr)
else:
break
t.update()
# t.refresh()
t.close()
def run(self):
for index in self.timer_list:
timer_cmd_list = ["self.timer_with_progress(5, 'Rest')",
"self.timer_with_progress(self.timer_list[index]['durationSeconds'], self.timer_list[index]['timerName'])"]
for cmd in timer_cmd_list:
if not self.wait:
exec(cmd)
else:
if self.kb_listener is None:
self.kb_listener = keyboard.Listener(on_press = self.on_press_or_release) # , on_release = self.on_press_or_release)
self.kb_listener.start()
self.kb_listener.join() # Waits until the key is pressed again
self.wait = not self.wait # Once the button is pressed again, it changes the flag
if __name__=="__main__":
tt = TimerTimer(filename)
tt.run()
所以经过一些研究,我发现 progressbar2 似乎实现了一个更好的中断来完成我的目标。见下文:
import progressbar
from pynput import keyboard
from time import sleep
class TimerTimer:
def __init__(self, fileLoc) -> None:
self.timer_list = self.get_timer_list(fileLoc)
self.timer_length = len(self.timer_list)
self.wait = False
def on_press(self, key):
pass
def on_release(self, key):
if key == keyboard.Key.space:
self.wait = not self.wait
printStr = "Paused..." if self.wait else "\nResuming..."
print(printStr)
elif key == keyboard.Key.esc:
print("Exiting")
exit()
def timer_with_progress(self, time_limit: int, name: str, iter:int=1) -> None:
"""Function that runs the progressbar2 progress bar.
Keyword arguments:
time_limit -- (int) The time limit (in seconds) for the progress bar.
name -- (string) The Name of the progress bar, or the brief description.
iter -- (int) The iteration time in seconds. (default 1)
"""
print("{} for {} seconds:".format(color.BOLD + name +color.END, time_limit))
bar = progressbar.ProgressBar(max_value=time_limit)
i = 0
# Adding keyboard listener
listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
listener.start()
while i <= time_limit:
sleep(iter)
if not self.wait:
bar.update(i)
i += iter
bar.finish()
def run(self):
for index in self.timer_list:
self.timer_with_progress(5, 'Rest')
self.timer_with_progress(self.timer_list[index]['durationSeconds'], self.timer_list[index]['timerName'])
if __name__=="__main__":
tt = TimerTimer(filename)
tt.run()