【问题标题】:Trying to create a mouse recorder, but it keeps looping endlessly?尝试创建鼠标记录器,但它一直在无休止地循环?
【发布时间】:2019-10-18 11:13:53
【问题描述】:

我正在尝试使用 Pynput,我开始创建一个简单的程序来记录鼠标的移动,然后在单击按钮后重放这些移动。

但是,每次我单击鼠标时,它都会开始疯狂并无休止地循环。我认为它正在以超高速进行动作,但我最终不得不 Alt-F4 来阻止它。

任何帮助将不胜感激。

import pynput

arr = []

from pynput import mouse

mou = pynput.mouse.Controller()

def on_move(x,y):
    Pos = mou.position
    arr.append(Pos)

def on_click(x, y, button, pressed):
    listener.stop()
    for i in arr:
        mou.position = i
    print("Done")

listener = mouse.Listener(on_move = on_move, on_click=on_click)
listener.start()

【问题讨论】:

    标签: python multithreading python-multithreading pynput


    【解决方案1】:

    在使用多个线程时必须小心(这里就是这种情况,因为mouse.Listener 在自己的线程中运行)。显然,只要你在回调函数中,所有的事件都会被处理,即使你已经调用了listener.stop()。所以回放的时候,对于你设置的每一个鼠标位置,都会调用on_move回调函数,这样鼠标位置就会再次添加到你的列表中,从而导致死循环。

    一般来说,在回调函数中实现太多功能(在本例中为“重放”)是不好的做法。更好的解决方案是使用事件来通知另一个线程鼠标按钮已被单击。请参阅以下示例代码。几点说明:

    • 我添加了一些打印语句来查看发生了什么。
    • 我在鼠标位置之间添加了一个小延迟,以便真正看到回放。 (注意:这也可能会使应用程序挂起时更容易中断!)
    • 我更改了一些变量名以使其更有意义。调用数组“arr”不是一个好主意。尝试使用真正描述变量的名称。在这种情况下,它是一个职位列表,所以我选择称它为positions
    • 我正在使用return False 来停止鼠标控制器。 documentation 声明“从任何地方调用 pynput.mouse.Listener.stop,引发 StopException 或从回调中返回 False 以停止侦听器。”但就个人而言,我认为返回 False 是最干净和最安全的解决方案。
    import threading
    import time
    
    import pynput
    
    positions = []
    clicked = threading.Event()
    controller = pynput.mouse.Controller()
    
    
    def on_move(x, y):
        print(f'on_move({x}, {y})')
        positions.append((x, y))
    
    
    def on_click(x, y, button, pressed):
        print(f'on_move({x}, {y}, {button}, {pressed})')
        # Tell the main thread that the mouse is clicked
        clicked.set()
        return False
    
    
    listener = pynput.mouse.Listener(on_move=on_move, on_click=on_click)
    listener.start()
    try:
        listener.wait()
        # Wait for the signal from the listener thread
        clicked.wait()
    finally:
        listener.stop()
    
    
    print('*REPLAYING*')
    for position in positions:
        controller.position = position
        time.sleep(0.01)
    

    请注意,当您在 Windows 命令提示符下运行此程序时,应用程序可能会挂起,因为您已按下鼠标按钮,然后开始发送鼠标位置。这会导致“拖动”移动,从而暂停终端。如果发生这种情况,您只需按 Escape,程序将继续运行。

    【讨论】:

      【解决方案2】:

      你让自己陷入了无限循环。我认为您在 on_click 方法中引用的侦听器可能为 null 或未定义。另外根据一些文档,我发现您需要为 on_click 方法返回 false 才能停止收听

      这是我在看的:

      https://pythonhosted.org/pynput/mouse.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-24
        • 2022-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多