Reputation: 39
I have a function in a tkinter application that does some operations on the content of the clipboard, pastes the result to a Text widget, and then should return to the previous application. For the last part I'm generating an Alt-Tab using pynput.
def invert_clipboard(e=None):
txt = root.clipboard_get()
if not txt:
return
tokens = re.split('\s+', txt.strip())
if len(tokens) >= 2:
out = tokens[len(tokens)-1].strip() + ', '
for i in range(len(tokens)-1):
out += tokens[i]
if i < len(tokens) - 2:
out += ' '
else:
out = txt.strip()
out += '#'
input_text.insert(tk.INSERT, out)
global dirty
dirty = True
thread = Thread(target=switch_window)
thread.start()
def switch_window():
root.update_idletasks()
with keyboard.pressed(Key.alt):
keyboard.press(Key.tab)
keyboard.release(Key.tab)
keyboard.release(Key.alt)
The function can be accessed via a menu item:
macros_menu.add_command(
label='Invert',
command=invert_clipboard,
accelerator="Ctrl+M"
or via a keyboard shortcut:
root.bind('<Control-m>', lambda event:invert_clipboard(None))
When called from the menu, everything works as intended; when called from the keyboard shortcut, the return to previous doesn't quite work. I see the group of thumbnails of the open apps, with the expected app highlighted, but pressing Enter is required to maximize it.
I assume I'm not handling the keyboard event correctly in the bind, but I have only a murky understanding of how to do so. Any suggestions? Thanks.
Upvotes: 2
Views: 490
Reputation: 8062
The Problem that you are facing is that you have an additional and unwanted modifier key pressed during the event and that changes the behavior. You can check this by just trying the key combination CTRL+ALT+TAB
without running any script. You could solve it by changing your bind
in a manner that it works without CTRL
or you release that key before you invoke your desired key combination.
import tkinter as tk
import ctypes
ALT = 0x12
TAB = 0x09
SHIFT = 0x10
CTRL = 0x11
PRESS = 0x0000
RELEASE = 0x0002
keyevent = ctypes.windll.user32.keybd_event
def show_next(event=None):
keyevent(CTRL,0,RELEASE,0)
keyevent(ALT,0,PRESS,0)
keyevent(TAB,0,PRESS,0)
keyevent(TAB,0,RELEASE,0)
keyevent(ALT,0,RELEASE,0)
def show_prev(event=None):
keyevent(CTRL,0,RELEASE,0)
keyevent(ALT,0,PRESS,0)
keyevent(SHIFT,0,PRESS,0)
keyevent(TAB,0,PRESS,0)
keyevent(TAB,0,RELEASE,0)
keyevent(SHIFT,0,RELEASE,0)
keyevent(ALT,0,RELEASE,0)
root = tk.Tk()
btn1 = tk.Button(root, text='Next', command= show_next)
btn1.pack(side=tk.RIGHT)
btn2 = tk.Button(root, text='Prev', command= show_prev)
btn2.pack(side=tk.LEFT)
root.bind('<Control-n>', show_next)
root.bind('<Control-p>', show_prev)
root.mainloop()
Upvotes: 1