简体   繁体   English

Python:使用键盘按键启动和停止线程

[英]Python: Start and stop thread using keyboard presses

I'm working on Python 3.8 and I'm trying to be able to toggle a thread on and off using a keyboard shortcut.我正在研究 Python 3.8,我正在尝试使用键盘快捷键打开和关闭线程。

This is my Thread class:这是我的线程 class:

import keyboard
from threading import Thread
import time

class PrintHi(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.active = False

    def run(self):
        while True:
            if self.active:
                print("Hi,", time.time())
                time.sleep(1)

It seems to work as intended I can start the thread and later change 'thread.active' to True or False depending on if I want to enable it or disable.它似乎按预期工作,我可以启动线程,然后根据我是要启用还是禁用,将“thread.active”更改为 True 或 False。

The problem is when I try to use it with the "keyboard" module it doesnt work as expected:问题是当我尝试将它与“键盘”模块一起使用时,它无法按预期工作:

class KeyboardHook(object):
    def __init__(self):
        self.thread = PrintHi()
        self.thread.start()
        self.set_keyboard_hotkeys()

    def toggle_print(self):
        print("Toggle Print")
        self.thread.active = not self.thread.active

    def set_keyboard_hotkeys(self):
        print("Setting hotkeys hooks")
        keyboard.add_hotkey('ctrl+c', self.toggle_print)
        keyboard.wait()


if __name__ == '__main__':
    hook = KeyboardHook()

These are the steps:这些是步骤:

  • I first create the thread, store it in 'self.thread' and start it.我首先创建线程,将其存储在“self.thread”中并启动它。
  • Then I set the keyboard hotkeys hooks然后我设置键盘热键挂钩
  • When I press 'ctrl+c' the 'toggle_print()' function should execute当我按 'ctrl+c' 时,'toggle_print()' function 应该执行
  • This should set the active property of the thread to True thus enabling the printing.这应该将线程的 active 属性设置为 True 从而启用打印。

The thread by itself works fine, and the keyboard hook by itself also works fine but when I combine both they don't work.线程本身工作正常,键盘挂钩本身也工作正常,但是当我将两者结合起来时,它们不起作用。

Does anyone have an idea of what I'm doing wrong?有谁知道我做错了什么? Is there a approach of toggling threads on and off by using keyboard shortcuts?有没有使用键盘快捷键打开和关闭线程的方法? In my application, I will have multiple threads that I will have to toggle on and off independently.在我的应用程序中,我将有多个线程,我必须独立地打开和关闭它们。

Thanks!谢谢!

I'd suggest to refactor your code a bit, namely to use Event in the printer thread instead of a bool variable to signal a print action, and to add logic which will allow you to stop the printer thread on program exit:我建议稍微重构您的代码,即在打印机线程中使用Event而不是bool变量来发出打印操作的信号,并添加允许您在程序退出时停止打印机线程的逻辑:

import time
from threading import Thread, Event

import keyboard


class PrintThread(Thread):
    
    def __init__(self): 
        super().__init__() 
        self.stop = False 
        self.print = Event()

    def run(self): 
        while not self.stop: 
            if self.print.wait(1): 
                print('Hi,', time.time())
    
    def join(self, timeout=None): 
        self.stop = True 
        super().join(timeout)

Also, I'd suggest to move the blocking code out from the KeyboadHook initializer to a separate start method:另外,我建议将阻塞代码从KeyboadHook初始化程序移出到单独的start方法:

class KeyboardHook: 

    def __init__(self):
        self.printer = PrintThread()
        self.set_keyboard_hotkeys()

    def toggle_print(self): 
        print('Toggle the printer thread...')

        if self.printer.print.is_set():
            self.printer.print.clear()
        else:
            self.printer.print.set()

    def set_keyboard_hotkeys(self):
        print('Setting keyboard hotkeys...')
        keyboard.add_hotkey('ctrl+p', self.toggle_print)

    def start(self): 
        self.printer.start()

        try:
            keyboard.wait()
        except KeyboardInterrupt:
            pass
        finally:
            self.printer.join()

Run it like this:像这样运行它:

hook = KeyboardHook()
hook.start()

This code works for me like a charm.这段代码对我来说就像一个魅力。

Some changes in KeyboardHook get it running: KeyboardHook 中的一些更改使其运行:

  1. You do not need to keyboard.wait()你不需要keyboard.wait()
  2. Start the thread after setting up hotkeys设置热键后启动线程
  3. Better change hot-key from ctrl-c to something else最好将热键从 ctrl-c 更改为其他内容
class KeyboardHook(object):
    def __init__(self):
        self.thread = PrintHi()
        self.set_keyboard_hotkeys()
        self.thread.start()

    def toggle_print(self):
        print("Toggle Print")
        self.thread.active = not self.thread.active

    def set_keyboard_hotkeys(self):
        print("Setting hotkeys hooks")
        keyboard.add_hotkey('ctrl+p', self.toggle_print)
        #keyboard.wait()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM