PyAutoGUI Shift-Down does Nothing - python

I have the following script that is intended to take a screenshot of a video every 5sec by taking a screenshot, then hitting shift-right to fast-foward to the next 5sec interval, repeat. It looks like the shiftdown is not working, as whenever i do it manually, it works but whenever I run the script, the right button works but no shift.
time.sleep(2)
while t < 20:
time.sleep(0.5)
pyautogui.keyDown('shiftleft')
time.sleep(0.5)
pyautogui.press('right')
pyautogui.keyUp('shiftleft')
time.sleep(2)
screenshot = pyautogui.screenshot()
screenshot.save(loc + str(t) + '.png')
t = t + 1
time.sleep(0.5)

I think you should use the pyautogui.hotkey() function instead.
Like this:
import pyautogui as pe
pe.hotkey('shift', 'left)
It basically does the same thing, it presses shift and left and does the thing.

Here's another answer that doesn't require installing pydirectinput. This answer applies to Windows only. From the comments in this question, having numlock or caps lock activated will break <shift> + <arrow> in pyautogui. To get around this, you'll have to detect if either numlock or capslock is active. To do that, you'll have to do Windows API calls. You can do the calls with built-in ctypes or pywin32
Here's an example for ctypes (ctypes code adapted from this answer):
import pyautogui
import time
mywin = pyautogui.getWindowsWithTitle("Notepad")[0]
mywin.activate()
time.sleep(2)
import ctypes
VK_CAPITAL = 0x14
VK_NUMLOCK = 0x90
user32 = ctypes.WinDLL('user32.dll')
if user32.GetKeyState(VK_CAPITAL):
# numlock is active, need to deactivate it before using <shift>+<arrow>
capslock = True
pyautogui.press('capslock')
else:
capslock = False
if user32.GetKeyState(VK_NUMLOCK):
# capslock is active, need to deactivate it before using <shift>+<arrow>
numlock = True
pyautogui.press('numlock')
else:
numlock = False
pyautogui.keyDown('shift')
pyautogui.press('right')
pyautogui.keyUp('shift')
if capslock:
pyautogui.press('capslock')
if numlock:
pyautogui.press('numlock')

If you are using Windows AND if you are willing to try a different module, pydirectinput seems to work better than pyautogui for <shift>+<arrow> key operations. I got the idea from this answer
The example below uses an open copy of Notepad. In Notepad, <shift> + <arrow> will select text. For this example to work, you'll want a some spaces in your file and the cursor would have to be to the left of at least one space.
import pyautogui
import pydirectinput
import time
mywin = pyautogui.getWindowsWithTitle("Notepad")[0]
mywin.activate()
time.sleep(2)
pydirectinput.keyDown('shift')
pydirectinput.press('right')
pydirectinput.keyUp('shift')

Related

Trying to accept the keyboard input 'R' alone or along side any other amount of keyboard inputs using either keyboard or pygame modules

import keyboard
import pygame
import mouse
import time
def press_X():
time.sleep(0.2)
keyboard.press('x')
time.sleep(0.6)
keyboard.release('x')
print('Command Executed - press_X')
#SA_R_X V_1.0
#------------------------------------------
while True:
try:
keyboard.add_hotkey('r', press_X)
time.sleep(0.5)
break
except:
keyboard.add_hotkey('r', press_X)
time.sleep(0.5)
break
the problem is the code cannot detect if 'r' is pressed when i am holding 'w' and/or 'space'... (well any key really)
I tried to use a try and except to handle a combination of any key + 'r'. But it did not work. All I need is for the code to be able to detect an 'r' input even if I am pressing/ holding another key at the same time. Then after this the code waits 0.2 seconds before holding down the 'x' key for 0.6 seconds and releasing. Any help is appreciated and it would be very helpful if you included a short explanation on where I went wrong and how you fixed it.
The documentation for this module can be found here. This is where all relevant information can be found.
The best way to do this, from my understanding, is to use an alternative function. If you want the program to continue to run, even though the key has not been pressed, then I suggest using the keyboard.on_press_key() function. This would mean that the rest of your program could still run, and your press_X() function could be run as a callback. Here is an example of how this code could be implemented.
import keyboard
import pygame
import mouse
import time
class App:
running = True
def press_X():
time.sleep(0.2)
keyboard.press('x')
time.sleep(0.6)
keyboard.release('x')
print('Command Executed - press_X')
App.running = False
#SA_R_X V_1.0
#------------------------------------------
keyboard.on_press_key('r', lambda x: press_X()) ## Adds an event listener for the r key
## This will stop execution if there is no code after this point
If you want it to stop the program and wait for the r key to be pressed, then you could use keyboard.wait(). This will basically pause your program until the key is pressed, after which your function would be run. For example, to replace the keyboard.on_press_key('r', lambda x: press_X()):
keyboard.wait('r')
press_X()
From my understanding, keyboard.add_hotkey() does not work in your situation because it is looking for an exact combination of keys being pressed, such as Ctrl+C, and will only go if only the keys in the hotkey are pressed.
I hope this helps, good luck!

Making keyboard shortcut, but it does not do anything

I am trying to make a shortcut to open google when I do the function normal it works but when I try to do it in a shortcut it doesn't work.
import pyautogui as pg
import keyboard
hotkey1 = "ctrl+alt+w"
def google():
pg.hotkey("win")
pg.typewrite("google\n", 0.05)
while True:
if keyboard.is_pressed(hotkey1):
google()
You only need a pause until pg can take over. It so happens that when you press the hotkey combo, you might accidentally hit some other keys and therefore it doesn't work as intended. This should give it enough time for the key to be depressed before the automatic process starts.
import time
def google():
time.sleep(0.25)
pg.hotkey("win")
pg.typewrite("google\n", 0.05)

Pynput and pyAutoGui can't hold keys

I wanted to make a simple macro to hold down 'W' for some time, but even simple script like this does not work.
import time
import pyautogui
from pynput.keyboard import Key, Controller
keyboard = Controller()
pyautogui.keyDown('w')
time.sleep(3)
pyautogui.keyUp('w')
time.sleep(5)
keyboard.press('w')
time.sleep(3)
keyboard.release('w')
If i test it in any text editor/text input window it will write one 'w' when script starts and anouther one after 8 seconds without holding/spaming it. And therefore it DOES NOT work in any games what should be the whole purpose of this script. I tried it in a huge variety of different games (Java Minecraft, source Gmod, Roblox and some unity games) and this script just was not working in any of them, but if a game has chat, search box or any other text input window, this script will write one 'w' and anouther one after some time in it.
I realy have no idea why this is happening, but i remembered that two years ago i tried to make similar script on pynput and it did work, so i tried installing old versions of pynput, but that did not help me as well...
So after a long time i could finaly take care of the issue, and i figured out that the source of the problem was in the Microsoft's DirectInput. Basically pynput and pyAutoGUI are not able to get in to DirectInput and there is no signal at all while I thought that there wwas a signal, but for so little amount of time that the games just were not able to pick it up. And the solution to this was pretty easy thanks to this guy PyAutoGUI not working? Use DirectInput. Thanks to his PyDirectInput librarry you are able to use python to emulate button presses and holdes in games!
This might be a start to work with:
#https://stackoverflow.com/questions/66284097/pynput-and-pyautogui-cant-hold-keys
#simulate keystroke for some amount of time
import msvcrt
import time
def press(char, duration, sleep, limit=None):
while True:
lim = limit
t1 = time.time()
while time.time() - t1 < duration: # do for duration specified
msvcrt.putch(char) # output character, putch() awaits a byte string
if lim: # limit specified?
lim -= 1
if lim == 0: # limit reached
break
time.sleep(SLEEP)
if msvcrt.kbhit(): # key pressed?
char = msvcrt.getch()
press(b'w', .001, 2, None)

pywinauto emulate zoom with CTRL scroll does not work

I am trying to perform the zoom in/out command with pywinauto.
I have two solutions in mind. The first one is emulating the CTRL + wheel command.
I must say the window seems to zoom in, but the wheel_dist parameter does not effect the amount of zoom.
import pywinauto
import random
app = pywinauto.application.Application(backend='uia').connect(title_re='BlueStacks')
win = app.top_window()
win.set_focus()
win_rect = win.rectangle()
coords = (random.randint(win_rect.left, win_rect.right), random.randint(win_rect.top, win_rect.bottom))
pywinauto.keyboard.send_keys('{VK_CONTROL down}')
pywinauto.mouse.scroll(coords=coords, wheel_dist=100)
pywinauto.keyboard.send_keys('{VK_CONTROL up}')
The second solution is emulate the CTRL + + command. The solution does not work.
pywinauto.keyboard.send_keys('{VK_CONTROL down}{+ 20}{VK_CONTROL down}')
I have read the documentation and I don't find anything wrong with my code. I suppose this operation is not fully supported, but I am here to listen and learn.
Any thoughts?
This code works:
pywinauto.keyboard.send_keys("{VK_CONTROL down}")
for i in range(9):
pywinauto.keyboard.send_keys("{+ down}")
time.sleep(0.01)
pywinauto.keyboard.send_keys("{+ up}")
time.sleep(0.01)
pywinauto.keyboard.send_keys("{VK_CONTROL up}")
But nothing is wrong with your code. You should add an issue in: https://github.com/pywinauto/pywinauto/issues

Which is the easiest way to simulate keyboard and mouse on Python?

I need to do some macros and I wanna know what is the most recommended way to do it.
So, I need to write somethings and click some places with it and I need to emulate the TAB key to.
I do automated testing stuff in Python. I tend to use the following:
http://www.tizmoi.net/watsup/intro.html
Edit: Link is dead, archived version: https://web.archive.org/web/20100224025508/http://www.tizmoi.net/watsup/intro.html
http://www.mayukhbose.com/python/IEC/index.php
I do not always (almost never) simulate key presses and mouse movement. I usually use COM to set values of windows objects and call their .click() methods.
You can send keypress signals with this:
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys("^a") # CTRL+A may "select all" depending on which window's focused
shell.SendKeys("{DELETE}") # Delete selected text? Depends on context. :P
shell.SendKeys("{TAB}") #Press tab... to change focus or whatever
This is all in Windows. If you're in another environment, I have no clue.
Maybe you are looking for Sendkeys?
SendKeys is a Python module for
Windows that can send one or more
keystrokes or keystroke combinations
to the active window.
it seems it is windows only
Also you have pywinauto (copied from my SO answer)
pywinauto is a set of open-source
(LGPL) modules for using Python as a
GUI automation 'driver' for Windows NT
based Operating Systems (NT/W2K/XP).
and example from the web page
> from pywinauto import application
> app = application.Application.start("notepad.exe")
> app.notepad.TypeKeys("%FX")
> app.Notepad.MenuSelect("File->SaveAs")
> app.SaveAs.ComboBox5.Select("UTF-8")
> app.SaveAs.edit1.SetText("Example-utf8.txt")
> app.SaveAs.Save.Click()
pyautogui is a great package to send keys and automate several keyboard / mouse related tasks. Check out Controlling the Keyboard and Mouse with GUI Automation and PyAutoGUI’s documentation.
You can use PyAutoGUI library for Python which works on Windows, macOS, and Linux.
Mouse
Here is a simple code to move the mouse to the middle of the screen:
import pyautogui
screenWidth, screenHeight = pyautogui.size()
pyautogui.moveTo(screenWidth / 2, screenHeight / 2)
Docs page: Mouse Control Functions.
Related question: Controlling mouse with Python.
Keyboard
Example:
pyautogui.typewrite('Hello world!') # prints out "Hello world!" instantly
pyautogui.typewrite('Hello world!', interval=0.25) # prints out "Hello world!" with a quarter second delay after each character
Docs page: Keyboard Control Functions.
More reading: Controlling the Keyboard and Mouse with GUI Automation (Chapter 18 of e-book).
Related questions:
Python GUI automation library for simulating user interaction in apps.
Python simulate keydown.
Two other options are:
pynput - https://pypi.org/project/pynput/ - which is for Windows (tested), Linux and MacOS- docs are at https://pynput.readthedocs.io/en/latest/
PyDirectInput - https://pypi.org/project/PyDirectInput/ - which is for Windows only and can be used with (or without) PyAutoGUI
Warning - if you are wanting to use keyboard control for games, then pynput doesn't always work - e.g. it works for Valheim, but not for the Witcher 3 - which is where PyDirectInput will work instead. I also tested PyDirectInput and it works for Half life 2 (as a test of an older game).
Tip - You will likely need to reduce (don't remove for games) the delay between character typing - use pydirectinput.PAUSE = 0.05
As an example, here is a function that allows virtual keyboard typing - currently only tested on Windows:
from pynput import keyboard
try:
import pydirectinput
pydirectinput.PAUSE = 0.05
except ImportError as err:
pydirectinput = False
print("pydirectinput not found:")
def write_char(ch):
upper = ch.isupper()
if pydirectinput and pydirectinput.KEYBOARD_MAPPING.get(ch.lower(), False):
if upper:
pydirectinput.keyDown('shift')
print('^')
pydirectinput.write(ch.lower(), interval=0.0)
print(ch)
if upper:
pydirectinput.keyUp('shift')
else:
keyboard.Controller().type(ch)
This allows a string to be sent in, with upper case alphabetic characters handled through pydirectinput. When characters don't simply map, the function falls back to using pynput. Note that PyAutoGUI also can't handled some shifted characters - such as the £ symbol, etc.

Categories

Resources