I created a small Python script using win32api to use on the popular game Cookie Clicker (a game where you have to click on a Big Cookie to gain points) just for fun. It has a function called "auto_clicker" that do just that: keeps clicking on the screen on the point the user defined. This is the script:
# -*- coding: utf-8 -*-
import win32con
import win32api
def clicker(x,y):
"""Clicks on given position x,y
Input:
x -- Horizontal position in pixels, starts from top-left position
y -- Vertical position in pixels, start from top-left position
"""
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
def auto_clicker(x = -1,y = -1):
"""Keep clicking on position x,y. If no input is given, gets from actual
mouse position.
"""
if x == -1 | y == -1:
x,y = win32api.GetCursorPos()
while True:
clicker(x,y)
It works nicely, but I want to make some improvements:
How can I get the cursor position only when the user clicks instead when the function is called? I would prefer to not add another module
since win32api seems to contain everything I needed. Tried this
method without success.
How can I detect a keypress like "Escape", so I can exit from my program without the ugly hack I am using now (Ctrl+Alt+Del seems to give SetCursorPos denied access, so Python throws a error and exit the program).
Can I make this program portable? Seems like I can do using Tkinter and generating a invisible Tk window, but I tried to write something without success.
I don't think with win32api you can listen to clicks you can just generate them (not sure though). However, try using pyHook, it's a simple api easy to use and can be found here http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=Main_Page. With pyhook you can create a listener to listen to a mouse event and upon a mouse click you can do whatever you want, the example in the link shows you how. As for key press, you can use the same api for that too, also an example is provided, good luck!
use pynput . It can control mouse, keyboard, etc.
examples:
from pynput.mouse import Button, Controller
mouse = Controller()
# Read pointer position
print('The current pointer position is {0}'.format(
mouse.position))
# Set pointer position
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
mouse.position))
# Move pointer relative to current position
mouse.move(5, -5)
# Press and release
mouse.press(Button.left)
mouse.release(Button.left)
# Double click; this is different from pressing and releasing
# twice on Mac OSX
mouse.click(Button.left, 2)
# Scroll two steps down
mouse.scroll(0, 2)
Related
I wanted to create an autoclicker that would "remember" current position of my mouse pointer, move to specific location on the desktop, perform a double click and then come back to where it was and will do this randomly every 1 to 4 seconds. This way I wanted to achieve an autoclick in a specific place and more or less be able to use my mouse to browse other stuff.
What I want to click is in a different window, it is a program that I leave open visible on one half of my desktop and on the other half I want to do other things. The problem is that auto clicker does not make the program an active window and the click does not work.
import pyautogui
import threading
import random
def makro():
z = random.randint(1,4) #timer set to random value between 1 and 4 seconds
(x, y) = pyautogui.position() #remember current position of mouse pointer
threading.Timer(z, makro).start()
pyautogui.doubleClick(1516, 141) #perform a double click in this location (this clicks do not make the window active and clicks do not work)
pyautogui.moveTo(x, y) #come back to original mouse pointer location
makro()
Thank you for help
I think adding
pyautogui.click(1516, 141) before pyautogui.doubleClick(1516, 141) could activate the window.
I'm on Windows OS and I'm trying to perform clicks on background (inactive) applications without bringing them to the front.
I've been successful in doing in in Microsoft Paint (painting a dot on a minimised paint instance) but for some reason this doesn't seem to work on a Java based application (RuneLite.exe) which I'm writing this program for.
Some additional information:
Paint has a lot of child windows and performing the click only seems to work when I execute it on a specific child window (class: Afx:00007FF758890000:8) this is the most inner window.
The RuneLite window structure is as follows:
RuneLite (class: SunAwtFrame)
unknown (class: SunAwtCanvas)
unknown (class SunAwtCanvas)
I've tried using the handle of all 3 of the above windows but none seem to work
The code is able to find the handle of the window and it is correct (checked with Spy++)
The window blinks orange in the taskbar after running the code so some event must have been fired
I have determined the coordinates by screenshotting the window and using paint to find coordinates of a specific location. (If there is a better way of doing this, please let me know)
from pywinauto.application import Application
amount = 2
handles = []
def start_apps():
for i in range(amount):
a = Application()
a.start("D:\\Users\\Arno\\AppData\\Local\\RuneLite\\RuneLite.exe")
time.sleep(15)
handle = a.window().child_window(class_name="SunAwtCanvas", found_index=1).handle # select the most inner window
handles.append(handle)
def do_click(h, x, y):
long_position = win32api.MAKELONG(x, y) # simulate the mouse pointer and send it to the specified coordinates
win32api.SendMessage(h, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position) # simulate mouse press
win32api.SendMessage(h, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position) # Simulate mouse up
start_apps()
print(handles)
time.sleep(20)
for h in handles:
do_click(h, 450, 290)
Output of the code
Does anyone know why this happens and how I could go about fixing it?
I'm trying to build create a script that does a few action inside an DirectX game.
I've got everything working exept for moving the mouse.
Is there any module avalable that can move the mouse, for windows (python 3)
Thanks!
I used pynput once in Python 2.7. I just checked under Python 3.7 and it moves the cursor alright. Sample code from linked source:
from pynput.mouse import Button, Controller
mouse = Controller()
# Read pointer position
print('The current pointer position is {0}'.format(
mouse.position))
# Set pointer position
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
mouse.position))
# Move pointer relative to current position
mouse.move(5, -5)
# Press and release
mouse.press(Button.left)
mouse.release(Button.left)
# Double click; this is different from pressing and releasing
# twice on Mac OSX
mouse.click(Button.left, 2)
# Scroll two steps down
mouse.scroll(0, 2)
Edit: Just successfully tested in a DirectX game.
Use a freeware App called sikulix. It will do wonders for you
I have this piece of code:
import bge
import GameLogic
import os
os.system("cls")
scene = GameLogic.getCurrentScene()
objects = scene.objects
objectCube = objects["Cube"]
visible = objectCube.visible
if visible == True:
objectCube.setVisible(False, True)
else:
objectCube.setVisible(True, True)
This code is supposed to toggle the visibility of an object but instead the object disappears and immediately reappears in a split second. It looks as if it just flickers. What am I doing wrong?
Also, don't worry about the other variables, they work fine. I have tested them using some Console outputs.
The problem: The mouse sensor sends two signals per click, one for mouse down and one for mouse up. Mouse down sends a positive signal while mouse up sends negative.
You can test this by holding the mouse button down, the cube will disappear and when you release the mouse it will return.
The solution: Use the sensor's positive property to determine if this is a mouse up or down event.
import bge
import GameLogic
import os
os.system("cls")
scene = GameLogic.getCurrentScene()
objects = scene.objects
objectCube = objects["Cube"]
visible = objectCube.visible
# get the mouse sensor
cont = bge.logic.getCurrentController()
sens = cont.sensors['Mouse']
if sens.positive: # positive means a down button event
if visible == True:
objectCube.setVisible(False, True)
else:
objectCube.setVisible(True, True)
The second parameter of setVisible set the game children objects visibility. You set it to True. In this case You hidden the main object and show the children objects.
Following to http://bgepython.tutorialsforblender3d.com/GameObject/setVisible recursive parameter does not mean recursive show/hide all children elements but set the visibility to children elements to True/False
Following to http://www.tutorialsforblender3d.com/BGE_Python/Sensors/Mouse/MouseSensor_LButton_getButtonStatus.html mouse event send two events mouse press and mouse release. Maybe You do not differentiate between press and release and call code twice?
The following code creates a window in which a python turtle follows wherever your mouse goes. However, it draws indescriminately of whether the user is clicking to draw or not. My code is the following:
Note: You must have pythonwin installed in order for this program to work properly
import turtle, win32api
while True:
# turtle.penup()
user = win32api.GetCursorPos()
mousepos = [user[0]-510,-1*(user[1])+ 410]
turtle.goto(mousepos)
turtle.onclick(turtle.pendown())
In theory, this would only draw when the user is pressing and holding the mouse, but it doesn't work in practice. The commented code will simply cause it to not draw at all. Any advice?
turtle.onclick(turtle.pendown())
Here, you are calling pendown(), which returns probably None; then you're passing this None to onclick(). It probably means "do nothing on a click". That's probably not what you want.
According to #Gibby's comment, you want:
def clicked(*args): # args ignored
turtle.pendown()
turtle.onclick(clicked)