0

I am looking for a way to break out of a function and the loop that it is called in with some sort of interrupt. Ideally if the user presses a particular key the loop ends and the code goes back to asking the user for an input.

Pseudo code below...

def main():

    #main loop
    while True:

        #user asked to select an option
        inp = input()

        if inp == "option_1":
            #option 1 loop
            while True:
                perform_option1()
        
        elif inp == "option_2":
            #option 2 loop
            while True:
                perform_option2()

        elif inp == "quit":
            #exit the program
            exit()

Just to be clear the program asks the user for an input. Based on that input we move into one of two infinite loops. I am looking for a way to break these loops when the user presses a particular key and go back to the initial loop where the program will ask the user for an input again. I do not want to use input() or any other method where the code needs to stop and wait for input. I feel like this can be solved by threading or maybe a custom exception (no idea how to do that currently) and have read several other similar questions but can't for the life of me wrap my head around a way to make this work.

If possible I would love to use a standard library to accomplish this. Thanks very much for your help.

Bvdb89
  • 11
  • 3

1 Answers1

0

First of all you need keyboard third party library, but you can use other libraries as well. I choosed keyboard. This library needs sudo privileges also.

subthread will listen for key q. If q was pressed, this subthread will send SIGUSR1 signal to mainthread. mainthread has SIGUSR1 handler, if SIGUSR1 signal is send to mainthread, then interrupted func will be run by mainthread. interrupted func will raise CancelException exception, this exception will be handled by mainthread because we use except CancelException block.

If any exception occur in signal handler function when you are in try block, you can catch this exception, and handle this exception in except block

Below code is very simple example, you need to modify it your case:

import signal
import os
import keyboard
import time

from threading import Thread

class CancelException(Exception):
    pass

def interrupted(signum, frame):
    raise CancelException

signal.signal(signal.SIGUSR1, interrupted)

def listen_for():
    keyboard.wait('q')
    print("q pressed")

    os.kill(os.getpid(), signal.SIGUSR1)

Thread(target=listen_for).start()

def f():
    while 1:
        print("1")
        time.sleep(1)

def g():
    while 1:
        print("2")
        time.sleep(1)

def main():
    #main loop
    while True:

        #user asked to select an option
        inp = input("give me an input: ")

        if inp == "1":
            while True:
                try:
                    f()
                except CancelException:
                    break
        elif inp == "2":
            while True:
                try:
                    g()
                except CancelException:
                    break


        elif inp == "quit":
            #exit the program
            exit()

main()
Veysel Olgun
  • 552
  • 1
  • 3
  • 15