Python Forum
How to break a loop in this case?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to break a loop in this case?
#1
I got this to work, but when I press s to stop the script, it will keep running the marketloop() function till end before stopping. My question is that how do I make the function stop instantly too? I tried adding break in stop buffing function but returned an expected 'break' outside loop error.

import pyautogui as pg import time import keyboard import random import win32api, win32con import threading from pynput.mouse import Button, Controller from pynput.keyboard import Listener, KeyCode start_stop_key = KeyCode(char='s') exit_key = KeyCode(char='q') def marketloop(): #this has code that clicks through lots of things class BuffItems(threading.Thread): def __init__(self): super(BuffItems, self).__init__() self.running = False self.program_running = True def start_buffing(self): self.running = True def stop_buffing(self): self.running = False def exit(self): self.stop_buffing() self.program_running = False def run(self): while self.program_running: while self.running: marketloop() buff_thread = BuffItems() buff_thread.start() def on_press(key): if key == start_stop_key: if buff_thread.running: buff_thread.stop_buffing() else: buff_thread.start_buffing() elif key == exit_key: buff_thread.exit() listener.stop() with Listener(on_press=on_press) as listener: listener.join()
Reply
#2
Hi,

Im not a 100% certain but hopefully this will help.

If you want the program to stop when you press the key "S". Then maybe something within the loop like.

if key_press = s: break
If you have that in the loop then it will check everytime the loop is run. As i said not 100% it will work but hopefully it helps.
"Only Boring People Get Bored"
Reply
#3
(Sep-24-2020, 05:19 AM)finndude Wrote: If you have that in the loop then it will check everytime the loop is run.

Thanks, I cut lot of it out but basically the marketloop looks like this, and when I added the code you provided on top, it still says the 'break' out of loop - error.

def marketloop(): if key_press == s: break offers = pg.locateCenterOnScreen('offers.PNG', region=(0,0,1919,1079), grayscale=False, confidence=0.80) time.sleep(0.5) pg.click(offers.x, offers.y) time.sleep(0.5) search = pg.locateCenterOnScreen('search.PNG', region=(0,0,1919,1079), grayscale=False, confidence=0.80) time.sleep(0.5) pg.click(search.x, search.y) time.sleep(0.5) settings = pg.locateCenterOnScreen('settings.PNG', region=(0,0,1919,1079), grayscale=False, confidence=0.80) time.sleep(0.5) pg.click(settings.x, settings.y) time.sleep(0.5) #lots of the same cut out
Reply
#4
What you show isn't a loop, it's a function. If you want to exit the function early, you use return.

Instead you need to find the (likely) loop where this function is called. You probably will be able to break or otherwise exit out of that loop.
Reply
#5
(Sep-24-2020, 06:45 AM)bowlofred Wrote: What you show isn't a loop, it's a function.

Ah, I kind of fooled myself by naming the function as loop, I guess :D Is there way to call that return outside of the function?
Reply
#6
I changed your code a bit.
Does marketloop require access to key events?
If it's the case, code needs to be changed. Again.

import pyautogui as pg import time import keyboard import random import win32api, win32con import threading from pynput.mouse import Button, Controller from pynput.keyboard import Listener, KeyCode class BuffItems(threading.Thread): def __init__(self): super().__init__() self.running = False self.pause = False def start(self): """ Duplicates the start method of threading.Thread """ if not self.running: self.running = True super().start() def stop(self): self.running = False def pause_toggle(self): self.pause = not self.pause def run(self): while self.running: time.sleep(0.5) # to reduce speed if not self.pause: marketloop() class KeyboardControl: start_stop_key = KeyCode(char='s') exit_key = KeyCode(char='q') def __init__(self): self.listener = Listener(on_press=self.on_press) self.listener.start() self.buff_thread = BuffItems() self.buff_thread.start() def __enter__(self): return self def __exit__(self, *args): self.buff_thread.stop() self.listener.stop() def on_press(self, key): if key == self.start_stop_key and self.buff_thread.running: self.buff_thread.pause_toggle() elif key == self.exit_key and self.buff_thread.running: self.buff_thread.stop() self.listener.stop() def join(self): while self.buff_thread.running: time.sleep(0.1) def marketloop(): print(time.time()) def main(): try: with KeyboardControl() as control: control.join() except KeyboardInterrupt: print("\nReceived SIGINT. Exitting programm.") if __name__ == "__main__": main()
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#7
Thanks, but I don't understand the changes :D I'm learning python, by jumping feet first and I barely managed to get the code work in the first place.. It would probably be too much to ask to explain the changes you made, so I won't.. Instead I'll keep hacking at it, I'll return to your post when I have learned a bit more!
Reply
#8
For beginners classes are not the best choice until object-oriented programming is understood.
Do you want a kind of interruption somewhere in the marketloop?
Also mine implementation has no method to stop marketloop doing its work when it was called.
Actually it would just print the time and your example has some time.sleep and stuff from pyautogui inside.
All this is executed, until the function is left and then the loop is calling again the marketplace function, if it was not stopped.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#9
Yes, I'm just looking for a way to stop a longer function (within a loop) with a press of a key. In my example the function is repeated as long as the program is running and as long as I don't press 's' key to stop it, but even then the function will run till completion before stopping the repetition.

Just to give an idea what the marketloop() is currently set to do, is that it will click though series of buttons to navigate in a game screen, so it will take a moment to finish with all the small sleeps in between the clicks. I want that to stop instantly when I press the button and not wait until it finish.
Reply
#10
Unless you create some sort of multi-threaded app (which is not easy), there's no way to stop a function from the outside. The outside program is just waiting for the function to return.

Some options:
That marketloop() function is doing a lot of repetitive things. A loop would be good for it. If you had the data in a nice map, you could loop over them, and then check for the keypress (and exit) if you see it.

files = { "offers": "offers.PNG" "search": "search.PNG" "settings": "settings.PNG" } def marketloop(): for region, filename in files.each(): data = pg.locateCenterOnScreen(filename, region=(0,0,1919,1079), grayscale=False, confidence=0.80) time.sleep(0.5) pg.click(data.x, data.y) time.sleep(0.5) if check_keypress() == pressed: #however you do this... return # Exits the function immediately.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Break within an if statement inside a while loop not working Python_more_on 2 1,839 Sep-03-2025, 12:55 AM
Last Post: Pedroski55
  Code won't break While loop or go back to the input? MrKnd94 2 2,740 Oct-26-2022, 10:10 AM
Last Post: Larz60+
  How to break out of a for loop on button press? philipbergwerf 6 4,636 Oct-06-2022, 03:12 PM
Last Post: philipbergwerf
  break out of for loop? User3000 3 3,215 May-17-2022, 10:18 AM
Last Post: User3000
  Asyncio: Queue consumer gets out of while loop without break. Where exactly and how? saavedra29 2 5,611 Feb-07-2022, 07:24 PM
Last Post: saavedra29
  Switch case or match case? Frankduc 9 9,784 Jan-20-2022, 01:56 PM
Last Post: Frankduc
  tkinter control break a while loop samtal 0 3,621 Apr-29-2021, 08:26 AM
Last Post: samtal
  Cannot 'break' from a "for" loop in a right place tester_V 9 6,488 Feb-17-2021, 01:03 AM
Last Post: tester_V
  how to break the loop? bntayfur 8 5,367 Jun-07-2020, 11:07 PM
Last Post: bntayfur
  break for loop Agusben 1 2,948 Apr-01-2020, 05:07 PM
Last Post: Larz60+

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.