Pause Python Code and continue after key press without selecting Terminal manually

112 Views Asked by At

I was trying around with making my own GUI and combining it with some pyautogui stuff and was trying in this case to create a button that moves the mouse to the first position, then waits there until any button on the keyboard is pressed and only then continues moving to the next position.

My problem is that it works, but only if I manually select the Terminal and then press any key to continue the code. However, I want it to continue without me having to manually select the Command Prompt / Terminal as I might also add later mouse clicks with pyautogui and select different windows with it.

I tried a few different methods such as using input() / msvcrt.getch() / keyboard.wait() but all of them ended with the same problem.

(I also tried converting the .py into a .exe in hopes that it might work but to no avail.)

Is there any way to pause it and let it continue after pressing any key without having to select the Terminal myself?

(Yes I'm still very new to coding and English is not my first language, so sorry if some things are not so easy to understand)

Edit: I see there has been some misunderstanding about what I am trying to achieve and what exactly my problem is so I'm going to try to explain it in a bit more detail.

I want to make an Interface with multiple buttons. Each button is supposed to run a function to automate simple things like a sequence of mouse clicks/key presses.

A different problem I was running into with something inside the sequence of clicks the button was supposed to do, was with my script not being able to detect if the other program it was supposed to click in was fully loaded yet or not. This is why I want my code to stop in between and only continue after I press a key.

The problem is after moving the mouse and clicking inside the different programs it is supposed to wait for a key press by me and then continue but it only listens to my key presses while my interface is still selected, once it clicks inside the different program it won't continue.

I saw a suggestion about using a keylogger to always listen to my keys but I couldn't yet figure out how to integrate such one within my script. Gonna look more into those when I have more time again.

Sorry if I'm not good at explaining things properly.

import customtkinter, pyautogui, time

customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")

def tryout():
    pyautogui.moveTo(1632,133)
    pyautogui.leftClick()
    print("Waiting for Key press...")
    input()
    print("Continuing...")
    pyautogui.moveTo(1792, 1076)
    pyautogui.leftClick()
    

root = customtkinter.CTk()
root.geometry("900x550")

frame = customtkinter.CTkFrame(master=root)
frame.pack(pady=20, padx=60, fill="both", expand=True)

button = customtkinter.CTkButton(master=frame, text="Test", command=tryout)
button.pack(pady=12, padx=10)

root.mainloop()
2

There are 2 best solutions below

0
Ramosv On

There is a way to pause your execution with the use of a breakpoint(), it is built into python, here is the documentation pdb. Please note that this is more of debugging tool, I am note entirely sure if this is what you are asking for. You can set multiple breakpoints in your code, then use continue(continue is an actual command you would run) to move to the next breakpoint() in your code. When you are done, you can use exit() to break out of the debugger. Try replacing it here in place of your input().

def tryout():
    pyautogui.moveTo(1632,133)
    print("Waiting for Key press...")
    breakpoint()
    print("Continuing...")
    breakpoint()
    pyautogui.moveTo(1792, 1076)
9
Suramuthu R On
  1. Change the order (i.e) Declare functions and then the design part of the code

  2. Make the button triggering the function tryout. And the function tryout will have two jobs.

    1.moves the mouse to the required position-1

    2.Bind keypress to another function move_after_keypress.

That's it. So after the mouse position got changed, If any key is pressed the function move_after_keypress will run.

  1. The function move_after_keypress will do 2 jobs.

    1. Unbind the bound key.

    2. Move the mouse to the desired position-2.

Please note that I could do this without importing the modules msvcrt, keyboard, and time.

import customtkinter
import pyautogui       
customtkinter.set_appearance_mode("dark")   
customtkinter.set_default_color_theme("dark-blue")

  
def move_after_keypress(event):

    #unbind the bound key
    root.bind('<Key>', lambda e:'break')

    print("Continuing...")
    pyautogui.moveTo(1792, 1076)
    

def tryout():

    pyautogui.moveTo(1632,133)
    
    #bind key to the function move_after_keypress()
    root.bind('<Key>', move_after_keypress)
       
          
root = customtkinter.CTk()
root.geometry("900x550")

frame = customtkinter.CTkFrame(master=root)
frame.pack(pady=20, padx=60, fill="both", expand=True)

button = customtkinter.CTkButton(master=frame, text="Test", command=tryout)
button.pack(pady=12, padx=10)

root.mainloop()

Edit: After seeing the OP's comment, I came to know that the OP's goal is after moving the mouse, the OP wants to click a button present in the new position which in turn runs another function. In short the OP's goal is either 1) to run multiple functions by clicking single button or 2)button-1 is meant to run function-A & button-2 if clicked it should run both function-A and function-B simultaneously. This can be achieved by the following methods.

This two buttons can either be there in a same window or different windows which doesn't matter

def function_A():
    #Do Something

def function_B():
    #Do Something


#This function is mapped with the button which triggeres the multiple functions
def multiple_functions():
    #Add as many functions as you want to run simultaneously in the following way.
    function_A()
    function_B()

root = customtkinter.CTk()
root.geometry("900x550")

btn_1 = Button(command= function_A)
btn_1.pack()

btn_2 = Button(command = multiple_functions)
btn_2.pack()


root.mainloop()

Edit 2: Even though, the actual goal of your code was unknown, with my explanations you can expand your idea. What I meant by multiple function is : Instead of auto-clicking another button to trigger another function, you can directly bind the respective function.

Also, the idea you should take from here is, how to make the mouse to wait for the users' keypress. That is just by binding and unbinding the key with mouse_leftclick. That is with the function tryout, the purpose of the line root.bind('<Key>', move_after_keypress) is : Once the mouse is moved to the reqd position, it binds '' to the next function. So, only if the user clicks any key, it'll go to the next function. The moment the next function starts, it unbinds using root.bind('<Key>', lambda e:'break'). You can expand this to whatever way you want.

For instance, if you want to press series of buttons after clicking the primary button. And before clicking each button, it waits for the user clicking any key: Here I've taken 3 positions. Now, I have changed the function move_after_keypress(event) to click_after_keypress(event). Keeping rest of the codes same, I've just changed the functions alone:

import customtkinter
import pyautogui       
customtkinter.set_appearance_mode("dark")   
customtkinter.set_default_color_theme("dark-blue")

positions_lst = [(1632,133), (1792, 1076), (1500, 232)]
L = len(positions_lst)


def click_after_keypress(event):
    i = i + 1

    #unbind the bound key
    root.bind('<Key>', lambda e:'break')
    pyautogui.click()
    print("Continuing...")
    if i != L : tryout(i)
    


def tryout(i = 0):
    x, y = positions_lst[i][0], positions_lst[i][1] 
    pyautogui.moveTo(x, y)

    #bind key to the function move_after_keypress()
    root.bind('<Key>', click_after_keypress)