Changing the active window with a hotkey using python - python

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.

Related

Does msvcrt not work with python GUI libraries like tkinter? Or is is the IDLE? New to python GUI

I am using the latest version of PyCharm and Python. I'm trying to get my program to wait for specific keypresses like the arrow keys. I've been messing with the mscvrt (not worried about only windows) and using the getch() but it freezes my program everytime. I was able to get it to work printing to the console by using "emulate terminal in output console". But once I tried implementing it to a GUI with my code in tkinter it still freezes. Was wondering if it just doesn't work in GUI's and that's the issue (saw this mentioned on the internet) and if anyone had suggestions for what I could do.
For example:
This runs in the console and works. The arrow keys print as (b'\xe0' b'K') (left) and (b'\xe0' b'M') (right)
while True:
if msvcrt.kbhit():
key = str(msvcrt.getch())
if key == "b'w'":
print(key)
elif key == 'w':
print("suck it")
This freezes my program before I get the chance to press any keys. It seems to be only when I introduce GUI into the program. I also tried binding this as a function to space and it will freeze the GUI when I press space and crash after a bit. I also tried not using a while function and also without the kbhit part as well.
while True:
if msvcrt.kbhit()
user_input = str(msvcrt.getch())
start = tk.Label(window, text=(user_input), font=("arial", '25'))
start.place(relx=.5, rely=.7, anchor="center")
Appreciate any help/advice. I'm somewhat new to python and coding so not sure what the issue could be.

Python disable keyboard input

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)

How do I print text at my current cursor position using python?

I am using Linux Mint 20 with Python 3. I am a complete noob with Python. However, I am trying to set up a keyboard shortcut to display certain text wherever my cursor is at in the active window (an input box, text editor, etc.). I know how to set up shortcuts and run simple python programs in Terminal.
It seems I have to use some type of GUI interface? I have looked at GTK and pkinter, but I can't seem to figure out the correct code. Would rather use GTK or something that already comes with the system.
Thanks.
You can use the pynput module to make keypresses wherever the cursor is. Here is an example:
import pynput
from pynput import keyboard
string_to_type = "Hello! How are you?"
c = keyboard.Controller()
for char in string_to_type:
c.tap(char)
c.tap() presses and then quickly unpresses the key passed as an argument.
You can also call c.press() and c.unpress(), both of which require an argument representing a key. This enables you to hold down keys.

Running Python clicker based on keylogger inputs on the background in Windows

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.

KUbuntu, Python and libtcod - console_is_window_closed not working...?

I've done a reasonable amount of coding with the libtcod library, both the C# and python wrappers. My current setup is KUbuntu 14.10, python 2.7.8, and libtcod 1.5.2.
I've made a few programs that work fine, but the latest I've just started doesn't seem to want to allow me to close the console window.
I can send a CTRL+C from the console that I run the program from, and it will close, but, no amount of clicking on the window's "x" button, or Alt+F4s seem to work.
My code is as follows:
'''
justclose.py
'''
import sys
import time
import libtcodpy as libtcod
libtcod.console_set_custom_font(b'lucida12x12_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
libtcod.console_init_root(50,50, "The ever-present window", False)
libtcod.console_flush()
while not libtcod.console_is_window_closed():
time.sleep(1)
sys.exit
When I run the program, the console comes up, as expected, and sits around waiting for console_is_window_closed to return true, which it never does. I'm not sure where the problem lies. I can run other programs that use the same initialisation code, and same while loop and which respond just fine to me clicking the close button on the console window.
I've tried looking through an strace of the process, but, I'm not sure I'm up to the task of deciphering it. Nothing looked immediately out of the ordinary.
I'd like some advice on how to track down what's going wrong. Thanks.
EDIT: specifically, I'd like to know how I can check that the close window event is propagating at all, and if so, how far, where it's getting trapped/ignored, that sort of thing. When I run through strace, I see absolutely nothing happening when I click the close button. Is there some better way to debug this?
Replace time.sleep(1) with libtcod.console_check_for_keypress(). When the program sleeps 1 millisecond for each iteration, the program can not respond when you press X. It exits when you press CTRL+C because the program receives the SIGINT signal and it exits immediately. Replacing time.sleep(1) with libtcod.console_check_for_keypress() makes the program check the key pressed on the keyboard, if there is one. That way, the program doesn't block the execution.

Categories

Resources