【问题标题】:pyHook and wxPython - App Freezes when typing in itselfpyHook 和 wxPython - 输入时应用程序冻结
【发布时间】:2014-05-25 23:27:16
【问题描述】:

我有一个小的 python 应用程序,它创建一个 wxPython 框架,然后使用 pyHook 来挂钩键盘。 Frame 包含一个 TextCtrl。当控件中的文本发生变化时,会创建一个线程来做一些过程(在这种情况下,只是一个大循环来模拟一个长过程)。

如果我专注于 TextCtrl 并敲击键盘,应用程序将完全锁定。如果我删除 pyHook 代码,应用程序不会锁定。如果我缩短长流程(例如仅循环 10 次迭代),应用程序不会锁定。

在创建它的同一个应用程序中键入时使用 pyHook 似乎有些问题。

请注意,如果我创建键盘挂钩并从主线程调用 PumpMessages,应用程序不会锁定,但理想情况下我希望在单独的线程上创建挂钩。

有什么想法吗?

谢谢 迈克

import threading
import pyHook
import pythoncom
import wx

class LargeTaskProcessor(object):

    def do_task(self):
        iterations = 1000000
        # Simulate some large process
        for i in range(iterations):
            pass

class TestFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, 1, 'Title', size=(400, 400))

        global_sizer = wx.BoxSizer(wx.VERTICAL)

        self.test_textbox = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
        self.Bind(wx.EVT_TEXT, self._event_happened, self.test_textbox)
        global_sizer.Add(self.test_textbox)

        self.SetAutoLayout(True)
        self.SetSizer(global_sizer)
        global_sizer.Fit(self)
        global_sizer.SetSizeHints(self)
        self.Layout()

    def _event_happened(self, event=None):
        action_thread = threading.Thread(target=obj.do_task)
        action_thread.start()

def hook_the_keyboard():
    hookManager = pyHook.HookManager()
    hookManager.HookKeyboard()
    pythoncom.PumpMessages()

if __name__ == '__main__':
    app = wx.App()

    obj = LargeTaskProcessor()

    dialog_instance = TestFrame()
    dialog_instance.Show()
    dialog_instance.Raise()

    # Create the hook manager and call PumpMessages on a separate thread
    theThread = threading.Thread(target=hook_the_keyboard)
    theThread.start()
    app.MainLoop()

【问题讨论】:

    标签: wxpython deadlock pyhook lockup


    【解决方案1】:

    尝试删除pythoncom.PumpMessages()

    来自pyHook turorial说:

    运行时,该程序只是处于空闲状态并等待 Windows 事件。如果您使用的是 GUI 工具包(例如 wxPython),则不需要此循环,因为该工具包提供了自己的。

    【讨论】:

    • 请包含一个代码示例,说明此方法在 OP 帖子中的哪些地方有用。
    • 只要从主线程调用“hook_the_keyboard”函数而不是像我的示例中那样作为单独的线程完成,它就可以工作。
    • 我现在从主线程调用 hook_the_keyboard 并且我已经删除了 PumpMessages 调用。这现在有效。谢谢!
    猜你喜欢
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多