pyautogui mouseDown()不适用于自动鼠标移动

pyautogui mouseDown() not working for automated mouse movement

在自动化无聊的事情的第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()

我发现你必须使用 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()

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

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

这是将任务分成两个线程并同时运行它们的代码的结果,正如您所看到的那样,角落是平滑的,而且都是一长行,就像我按下 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()

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