I have a program that runs a while loop (using pyautogui & pysimplegui). I want to allow the user to manually cancel the loop / stop the program.
Currently (on mac) if I try to interact with the main pyautogui window in any way I get a spinning beach ball.
I believe threading may be the answer but I can't seem to get it to work in my code after much searching and testing.
Below is the loop in question:
window=sg.Window('Meetup Auto Message', layout1, element_justification='c')
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, ' Cancel '):
break
if event == ' Ok ':
messageOptions = [values['textBox1'], values['textBox2'], values['textBox3'], values['textBox4'], values['textBox5']]
for i, (nameList, profileLink) in enumerate(zip(nameList, profileLink)):
message = "Hi " + f'{nameList}' + ", " + "\n" + f'{choice(messageOptions)}'
webbrowser.open(profileLink)
time.sleep(15)
pyautogui.press("tab")
pyautogui.write(message, interval=random.uniform(0.03, 0.15))
with pyautogui.hold("command"):
pyautogui.press("w")
window['-PROG-'].update(i+1)
if i == 10:
time.sleep(300)
window.close()
And for reference the full code:
import webbrowser
import pyautogui
import random
from random import choice
import time
import PySimpleGUI as sg
import threading
font = ("Arial", 13)
layout = [ [sg.Text('Select your .txt profiles file. Must be a list of URLs with each URL on a new line', font=("Arial", 16))],
[sg.Combo(sorted(sg.user_settings_get_entry('-filenames-', [])), default_value=sg.user_settings_get_entry('-last filename-', ''), size=(50, 1), key='-FILENAME-', font="Arial, 16"), sg.FileBrowse(font="Arial, 16"), sg.B('Clear History', font="Arial, 16")],
[sg.Button(' Ok ', bind_return_key=True, font="Arial, 16", button_color='green'), sg.Button('Cancel', font="Arial, 16")] ]
window = sg.Window('Meetup Auto Message - Profiles selection', layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Cancel'):
break
if event == ' Ok ':
# If OK, then need to add the filename to the list of files and also set as the last used filename
sg.user_settings_set_entry('-filenames-', list(set(sg.user_settings_get_entry('-filenames-', []) + [values['-FILENAME-'], ])))
sg.user_settings_set_entry('-last filename-', values['-FILENAME-'])
lastFile=values['-FILENAME-']
break
elif event == 'Clear History':
sg.user_settings_set_entry('-filenames-', [])
sg.user_settings_set_entry('-last filename-', '')
window['-FILENAME-'].update(values=[], value='')
window.close()
profileLink = open(lastFile).read().splitlines()
profileLink = [item.replace("+","name=") for item in profileLink]
newLinks = [item.replace("%","name=") for item in profileLink]
nameList = [i.split("name=")[1] for i in newLinks]
num_lines = sum(1 for line in open(lastFile))
BAR_MAX = num_lines
layout1 = [ [sg.Text('This program will take your messages, rotate them, add random delays and automatically message people from your profile list. You won\'t be able to use your computer while the program is running.', font="Arial, 18")],
[sg.Text('Enter your messages below just the content, we handle the "Hi Name" part.', font="Arial, 18")],
[sg.Multiline(size=(100,10), key='textBox1', font=font)],
[sg.Multiline(size=(100,10), key='textBox2', font=font)],
[sg.Multiline(size=(100,10), key='textBox3', font=font)],
[sg.Multiline(size=(100,10), key='textBox4', font=font)],
[sg.Multiline(size=(100,10), key='textBox5', font=font)],
[sg.Button(' Ok ', bind_return_key=True, font="Arial, 24", button_color='green'), sg.Button(' Cancel ', font="Arial, 24")],
[sg.Text('Progress Bar', font="Arial, 15")],
[sg.ProgressBar(BAR_MAX, orientation='h', size=(20,20), key='-PROG-')] ]
window=sg.Window('Meetup Auto Message', layout1, element_justification='c')
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, ' Cancel '):
break
if event == ' Ok ':
messageOptions = [values['textBox1'], values['textBox2'], values['textBox3'], values['textBox4'], values['textBox5']]
for i, (nameList, profileLink) in enumerate(zip(nameList, profileLink)):
message = "Hi " + f'{nameList}' + ", " + "\n" + f'{choice(messageOptions)}'
webbrowser.open(profileLink)
time.sleep(15)
pyautogui.press("tab")
pyautogui.write(message, interval=random.uniform(0.03, 0.15))
with pyautogui.hold("command"):
pyautogui.press("w")
window['-PROG-'].update(i+1)
if i == 10:
time.sleep(300)
window.close()
Bonus points if you can show me how to implement the GUI to break the loop! :)
EDIT: I've tried refactoring while loops to functions, allowing me to use try: except: on the functions... no luck. When doing so I get value not defined. So I put the event, value window.open outside of the function... tried declaring global variables and so on... this led to the program crashing with an error of "could not read settings file" when hitting the clear button on my program.
At a loss here.