【问题标题】:Python: Start and stop thread using keyboard pressesPython:使用键盘按下启动和停止线程
【发布时间】:2020-06-20 08:49:58
【问题描述】:

我正在使用 Python 3.8,我正在尝试使用键盘快捷键打开和关闭线程。

这是我的线程类:

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)

它似乎按预期工作,我可以启动线程,然后根据我是要启用还是禁用,将 'thread.active' 更改为 True 或 False。

问题是当我尝试将它与“键盘”模块一起使用时,它无法按预期工作:

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()

这些是步骤:

  • 我首先创建线程,将其存储在“self.thread”中并启动它。
  • 然后我设置键盘热键挂钩
  • 当我按下 'ctrl+c' 时,'toggle_print()' 函数应该会执行
  • 这应该将线程的 active 属性设置为 True 从而启用打印。

线程本身工作正常,键盘挂钩本身也工作正常,但是当我将两者结合起来时,它们不起作用。

有人知道我做错了什么吗?有没有使用键盘快捷键打开和关闭线程的方法?在我的应用程序中,我将有多个线程,我必须独立地打开和关闭。

谢谢!

【问题讨论】:

    标签: python python-3.x multithreading


    【解决方案1】:

    我建议稍微重构您的代码,即在打印机线程中使用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)
    

    另外,我建议将阻塞代码从 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()
    

    像这样运行它:

    hook = KeyboardHook()
    hook.start()
    

    这段代码对我来说就像一个魅力。

    【讨论】:

      【解决方案2】:

      KeyboardHook 中的一些更改使其运行:

      1. 你不需要keyboard.wait()
      2. 设置热键后启动线程
      3. 最好将热键从 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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多