python-3.xmousepython-multithreadingpyautogui

Python: pyautogui mouse movement in Thread is slow and unreliable


I am attempting to automate some mouse movement to a certain position in Python 3. For this, I am using a module pyclicker, specifically the HumanClickerclass from the module. It uses an algorithm to calculate a 'human-like' flow of points to the mouse movement. For actually moving it along the calculated points it uses pyautogui.moveTo(). From pyclicker.HumanClicker:

    def move(self, toPoint, duration=2, humanCurve=None):
        fromPoint = pyautogui.position()
        if not humanCurve:
            humanCurve = HumanCurve(fromPoint, toPoint)

        pyautogui.PAUSE = duration / len(humanCurve.points)
        for point in humanCurve.points:
            pyautogui.moveTo(point)

I get some very nice results with moving the mouse and speeding up/slowing down, but moving the mouse with pyautogui (and because of that also with this HumanClicker) locks up the program until it is done moving. To fix this, I put the handling of the mouse movement into a separate thread whenever needed. My code for calling the move():

    def move(self, location, time):
        try:
            hc = HumanClicker()
            hc.move(location, time)
        except TypeError:
            pass

Where location is an (x, y) tuple and time a float (currently 0.2). Threading the movement works, but it significantly slows down the movement and makes it much more erratic/stuttery (both scale exponentially with the distance it has to travel). Threading it in any way gives the same results. I can provide a recording of the movement if needed.

Is there any specific reason for this slowing down/stuttering interaction?

Is there a module I could replace pyautogui with to make it not have these problems in threading?

Or is there any other way to fix this issue?


Solution

  • I don't know if you are still interested but I've found the problem on this issue.

    Apparently the moveTo() function is defined as def moveTo(x=None, y=None, duration=0.0, tween=linear, logScreenshot=False, _pause=True):

    So simply adding the argument _pause=False on your call should fix the issue as it did for me.