I’m pretty new to Python, and I’m really struggling to programmatically get the mouse to move in a circular motion.
I have found countless articles about how to draw circles, but I don’t want to draw anything, I just need the mouse to move.
I have found one code example that is actually doing the task I want it to, however this code takes 40 seconds to execute. I need this circle to be completed in under a second.
import pyautogui
import math
# Radius
R = 400
# measuring screen size
(x,y) = pyautogui.size()
# locating center of the screen
(X,Y) = pyautogui.position(x/2,y/2)
# offsetting by radius
pyautogui.moveTo(X+R,Y)
for i in range(360):
# setting pace with a modulus
if i%6==0:
pyautogui.moveTo(X+R*math.cos(math.radians(i)),Y+R*math.sin(math.radians(i)))
What a weird way of implementing an iteration step. This way is more natural and efficient (just the loop):
STEP = 6
for i in range(0, 360, STEP):
pyautogui.moveTo(X+R*math.cos(math.radians(i)),Y+R*math.sin(math.radians(i)))
I would also de-duplicate the code and improve readability:
STEP = 6
for angle_deg in range(0, 360, STEP):
angle_rad = math.radians(angle_deg)
pyautogui.moveTo(
X + R * math.cos(angle_rad),
Y + R * math.sin(angle_rad))
I guess that the call pyautogui.moveTo() takes a lot of time (about 0.7 seconds per single call?). Try to increase the STEP. …or maybe there is a different library which is able to position the mouse cursor faster.
I wanted to see what could be done with a tkinter canvas. It cannot move the user mouse pointer, but it can move anything one can draw, include unicode characters.
from math import *
from time import sleep
from tkinter import *
root = Tk()
can = Canvas(root, width=1000, height=1000)
can.pack()
x0, y0, r, steps = 500, 500, 400, 360
x, y = x0+r, y0
wid = can.create_text(x, y, text='x')
can.update()
rad, radstep = 0, 2 * pi / steps
for i in range(steps+1):
xold, yold = x, y
cr, sr = cos(rad), sin(rad)
x = int(x0 + r*cr + (.5 if cr >= 0 else -.5))
y = int(y0 + r*sr + (.5 if sr >= 0 else -.5))
can.move(wid, x-xold, y-yold)
rad += radstep
can.update()
sleep(.05)
With sleep(.05), it takes about 16 seconds. Without, it is too fast to see the movement. A proper tkinter program would use mainloop and after callbacks instead of update and for. Delays could then by specified in milliseconds.