I want to change the active window to a particular one using python. Here is a working example:
import pygetwindow as gw
win = gw.getWindowsWithTitle('editor')[0]
win.activate()
What I'd like to do however, is triggering the switch of windows using a hotkey, for instance like this:
import pygetwindow as gw
import keyboard as kb
def change_window():
win = gw.getWindowsWithTitle('editor')[0]
win.activate()
kb.add_hotkey('q', change_window)
kb.wait('esc')
I would expect the above code to do exactly the same as the first one after pressing the "q" key. However, the second code produces an error message. I really can't understand how the fact that it is triggered by a hotkey could change anything. I have tried different hotkeys and inserted a few time.sleep in between to see if it has anything to do with me still having the hotkey pressed, but to no success. It even works if I just call the function directly in the source code.
I would appreciate your feedback very much. I'm using PyCharm on Windows 11.
I'm trying to use Pynput to move my Minecraft character, but when I press run, it finishes without moving my character. I've retested it on stuff like the Minecraft chat and it works fine, I've also tested it on the Google Chrome search and it works, but weirdly not in Minecraft. My code is very simple.
from pynput.keyboard import Key, Controller
import time
myKeyboard = Controller()
time.sleep(3)
myKeyboard.press('w')
myKeyboard.release('w')
time.sleep(3)
myKeyboard.press('s')
myKeyboard.release('s')
I don't see anything wrong with my code and I don't know if pynput even works with moving Minecraft characters, or any characters for that matter.
According to pynput documentation, keeping a button pressed is best used with the pressed method and a with statement, like this:
with myKeyboard.pressed('w'):
time.sleep(3)
It should in theory hold the w key pressed for 3 seconds.
Is there a way to disable (keyboard) input on windows with python. I would like to convert this program to exe and the
from ctypes import *
ok = windll.user32.BlockInput(True) #enable block
method is not suitable for that (as it needs admin privileges). I looked at other articles with described how using the pyHook would work. Unfortunatelly this method is a bit old and does not work for me anymore, it just makes the mouse and keyboard lag a little bit.
There is a working method by just putting keystrokes (from for example the pynput library) in a while loop, so it just spams keystrokes and the user can not overwrite this by typing lets say alt+f4. This is a very dirty way and I would like a cleaner way(this method causes the computer to lag for a minute because it cant comprehend that amount of input in such a short time)
#### Blocking Keyboard ####
import keyboard
#blocks all keys of keyboard
for i in range(150):
keyboard.block_key(i)
So I've been working on a small project which will essentially be a macros program. The idea is to use a small external numpad with custom labels to click certain areas of the screen which correspond to buttons. I've got this all working beautifully with one minor (or major?) caveat which is the fact that I cannot differentiate between keyboards. Ideally I'd like to be able to still use my main keyboard and numpad normally. My code below for a sample key:
import keyboard
import pynput
from pynput.mouse import Button, Controller
import time
mouse = Controller()
tab = (1639, 16)
def handler():
print(keyboard.KeyboardEvent.device)
prev = mouse.position
mouse.position = tab
mouse.click(Button.left, 1)
mouse.position = prev
keyboard.add_hotkey("a", handler, suppress=True)
while True:
time.sleep(0.1)
So you can see here I am using the keyboard and pynput libraries. In the docs for the keyboard library, it notes an issue where on windows specifically, keyboard.KeyboardEvent.device returns "None" always.
I looked around a bit at various solutions for using raw input, but I wasn't able to really find anything applicable to my situation, and anything that looked remotely close was admittedly beyond my skill level. Anybody have any thoughts? Thanks.
I wanted to write a program in Python for Windows that would act as a clicker, in which according to a key the user presses a click is made at a known location on the screen. This is used for an automated option selection from a list in a webpage. I have the clicking part working, but I wanted to be able to make several clicks during execution, as if there is a quiz with multiple lists one after another.
One option is to make a while loop with getch() from msvcrt. The thing is after a click outside the cmd its window is no longer selected, but rather the window where the destination point is located. Therefore, the script stops being active and the user cannot choose another location. A workaround is to click the cmd window to return the focus to it and be able to do any more clicks. To solve this, it would be necessary to create a service or, according to #Sanju, a thread.
The other option is to use a keylogger such as PyHook, which seems like the way to go. However, the problem is that the window where I want to use it in, a webpage in flash or another animations engine, causes an error that some users have found using this keylogger for example in Skype and is being described here. In my case, it also happens with this webpage and either when the click is made on the window itself or when the key is pressed with the window selected.
My base code is presented below, where click(...) would normally contain the coordinates as argument but they are being omitted for simplicity. In this case, 0 ends the program and there are three options being chosen with the numbers 1-3.
import msvcrt, win32api, win32con
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
key=0
while key!=b'0':
key=msvcrt.getch()
if key==b'1':
click(...)
elif key==b'2':
click(...)
elif key==b'3':
click(...)
The attempts below try to implement #Sanju's suggestion, first with the whole while inside the thread and then with the queue, both not working as expected...
import threading, msvcrt, win32api, win32con
def MyThread():
key=0
while key!=b'0':
key=msvcrt.getch()
if key==b'1':
...
def click(x,y):
...
threading.Thread(target=MyThread,args=[]).start()
.
import queue, threading, msvcrt, win32api, win32con
def MyThread(key):
while key.get()!=b'0':
key.put(msvcrt.getch())
if key.get()==b'1':
...
def click(x,y):
...
key=queue.Queue()
key.put(0)
threading.Thread(target=MyThread,args=[key]).start()
The other attempt uses PyHook, but it's still facing the aforementioned issue.
import pyHook, pythoncom, win32api, win32con
def OnKeyboardEvent(event):
if event.Key=='Numpad1':
...
def click(x,y):
...
hm=pyHook.HookManager()
hm.KeyDown=OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
All you need here is move your click part to a thread and share the user input using a shareble object such as queue. It sounds like a overkill , but that's the way to keep your tasks in background.
And BTW, you have many GUI application frameworks available in Python like tkinter ,wxpython which can ease your objective.