2

I wrote this little program which spams in messenger for me. But I can't make it to stop if I want to. I tried to put 'try / except: KeyboardInterrupt' in the loop but it did not help.

I need python to somehow check if I press some key and if it's pressed break the loop. Also I know there is a after() method in Tkinter, and I should use it instead of time.sleep, but my attempt failed. Here is my code:

from tkinter import *
import time
import pyautogui

root = Tk()
root.title('Typer')
text_field = Text(root, height=20, width=40)
button = Button(text='----Start----')


def typer(event):
    text = text_field.get("1.0",END)
    time.sleep(5)
    for i in text.split(' '):  
        pyautogui.write(i)
        pyautogui.press('enter')


button.bind('<Button-1>', typer)

text_field.pack()
button.pack()
root.mainloop()

Update: I manage to change time.sleep() to after() by doing this:

def typer(event):
    def innertyper():
        for i in text.split(' '):
            pyautogui.write(i)
            pyautogui.press('enter')
    text = text_field.get("1.0",END)
    root.after(5000, innertyper)

But I still can't break the for loop

  • 1
    Does this answer your question? [tkinter and time.sleep](https://stackoverflow.com/questions/10393886/tkinter-and-time-sleep) – jasonharper Jun 25 '20 at 18:02
  • @jasonharper Well, it's not really a duplicate because the OP says he doesn't know how to use `.after()`. – 10 Rep Jun 25 '20 at 22:55
  • 1
    If you want to break a loop, you should check for some condition inside the loop. But there is no such code inside your code. – acw1668 Jun 26 '20 at 00:41
  • How exactly do you want to stop the loop? Do you want to have to type in the shell or do you want to just press any key or do you want to press a key whilst in the tkinter window? – TheFluffDragon9 Jun 26 '20 at 13:55
  • @TheFluffDragon9 I want to stop it by pressing key I specify in the code, Esc for example – Ivan Sivchev Jun 26 '20 at 14:03

1 Answers1

0

You should first add a statement that checks if it should still be running:

def typer(event):
    global running
    running = True
    text = text_field.get("1.0",END)
    time.sleep(5)
    for i in text.split(' '):
        if running == False: #Will break the loop if global variable is changed
            break
        pyautogui.write(i)
        pyautogui.press('enter')

Then are a couple of options to choose from; You can use tkinter's bindings (Which will only work within the tkinter window)

root.bind("<Escape>", stop)

def stop(event):
    global running
    running = False

If you don't want to have to click into the window I would recommend using keyboard pip install keyboard

Either do:

keyboard.on_press_key("Esc", stop)

or:

def typer(event):
    text = text_field.get("1.0",END)
    time.sleep(5)
    for i in text.split(' '):
        if keyboard.is_pressed("Esc"): #Will break the loop if key is pressed
            break
        pyautogui.write(i)
        pyautogui.press('enter')

I apologise for the janky code but hopefully you get the idea. I haven't tested it so let me know if you have problems.

TheFluffDragon9
  • 514
  • 5
  • 11
  • Thank you! I didn't manage to stop it by pressing key, it's seems too complicated, your suggestions didn't help :( So I added stop button and binded it to stop(event) and it worked for me! – Ivan Sivchev Jun 26 '20 at 19:34
  • Actually no :( It doesn't work, previously I did bad tests, but anyway thank you, I will keep trying to make it work. When button pressed the loop is continuing to do its work and stop function calls in the end – Ivan Sivchev Jun 26 '20 at 20:00