【问题标题】:pyautogui mouseDown() not working for automated mouse movementpyautogui mouseDown() 不适用于自动鼠标移动
【发布时间】:2021-01-02 19:52:36
【问题描述】:

在 Automate the Boring Things 的第 20 章中,有一个使用 pyautogui 绘制螺旋的示例。代码使用.drag() 绘制每个段,但在每个角上,鼠标释放光标并开始新行。无论您使用哪种刷子类型,这都会在每个角落创建一个中断。

为了解决这个美学问题,我尝试修改代码以改用.mouseDown().move()。然而,这最终只绘制了一条从左上角到左下角的线,就好像 while 循环的每次迭代都在重复单击一样。

通过测试:

while True:
    pyautogui.mouseDown()

在 mspaint 中,当我自己移动鼠标时,.mousedown() 函数确实可以正常执行。

尝试:

while True:
    pyautogui.mouseDown()
    pyautogui.move(300, 0, duration=0.5)

也正确地绘制了一条线,但在 300 像素块中这样做。 IE。每次循环迭代时,线段都会在 mspaint 上加载。

在正方形中重复这个实验:

while True:
    pyautogui.mouseDown()
    pyautogui.move(300, 0, duration=0.5)
    pyautogui.move(0, 300, duration=0.5)
    pyautogui.move(-300, 0, duration=0.5)
    pyautogui.move(0, -300, duration=0.5)

最终什么都没画。

这里发生了什么?为什么.mouseDown() 的行为如此不一致?如何让我的代码绘制出漂亮的完整螺旋?

完整的原始代码供参考:

#! python3
# spiralDraw.py - draws a spiral in mspaint

import pyautogui
import time

time.sleep(5)   # give time to go to paint app
distance = 300
change = 20
pyautogui.mouseDown()

while distance > 0:
    pyautogui.move(distance, 0, duration=0.5)   
    distance = distance - change
    pyautogui.move(0, distance, duration=0.5)   
    pyautogui.move(-distance, 0, duration=0.5)  
    distance = distance - change
    pyautogui.move(0, -distance, duration=0.5)
    
if distance == 0:
    pyautogui.mouseUp()

【问题讨论】:

    标签: python python-3.x pyautogui


    【解决方案1】:

    我发现你必须使用drag 来画一条线,因为move 函数只会移动指针而不会向下单击(documentation)。

    但是您仍然可以使用mouseDown 函数而不是click 函数,因为它“与单击鼠标左键的作用相同” (documentation)。

    drag 函数(至少在软件包的最后一个版本中)需要一个名为 button 的参数,它可以是 "left""right""middle",代表鼠标的三次点击中的每一次(documentation)。

    根据前面的信息,代码为:

    import pyautogui
    import time
    
    time.sleep(5)  # give time to go to paint app
    distance = 300
    change = 20
    pyautogui.mouseDown()
    
    while distance > 0:
        pyautogui.drag(distance, 0, duration=0.5, button='left')
        distance = distance - change
        pyautogui.drag(0, distance, duration=0.5, button='left')
        pyautogui.drag(-distance, 0, duration=0.5, button='left')
        distance = distance - change
        pyautogui.drag(0, -distance, duration=0.5, button='left')
    
    if distance < 0:
        pyautogui.mouseUp()
    

    【讨论】:

    • 如果您使用非像素画笔类型,这仍然会导致结果出现断角。您的代码让我得到以下信息:i.imgur.com/tGJnpC3.png
    • 我找到了一种方法来实现涉及多线程的预期行为,但我不知道为什么没有它代码就无法工作。我在这个问题线程中发布了答案。
    【解决方案2】:

    虽然我不确定为什么会出现这种情况,但可以通过将鼠标按住和鼠标移动分成单独的线程并同时运行它们来实现所需的结果。

    这是使用蜡笔画笔的非多线程代码的输出,请注意通过拖动实现的块状角落,因为每一行都是单独的鼠标按下:

    这是将任务分成两个线程并同时运行它们的代码的结果,你可以看到角落是平滑的,而且当我按下ctrl+z时,它都是一条长线,整个绘图消失了:

    下面是简单实现多线程的代码:

    import pyautogui
    import time
    import threading
    
    def mouseHoldDown():
        global distance
        while distance > 0:
            pyautogui.mouseDown()
        if distance == 0:
            time.sleep(1)
            pyautogui.mouseUp()
        
    def movingSpiralMouse():
        global distance
        change = 20
        while distance > 0:
            pyautogui.move(distance, 0, duration=0.25)
            distance = distance - change
            pyautogui.move(0, distance, duration=0.25)
            pyautogui.move(-distance, 0, duration=0.25)
            distance = distance - change
            pyautogui.move(0, -distance, duration=0.25)
    
    distance = 300
    time.sleep(5)
    
    mouseObj = threading.Thread(target=mouseHoldDown)
    mouseObj.start()
    
    moveObj = threading.Thread(target=movingSpiralMouse)
    moveObj.start()
    

    我仍然非常感谢您解释为什么需要将其分成多个线程以达到预期的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-23
      • 2021-04-03
      • 2019-04-13
      • 2022-11-18
      • 2021-06-16
      • 1970-01-01
      • 2021-05-17
      • 2021-11-03
      相关资源
      最近更新 更多