You can try wrapping that code in a try/except block, because keyboard interrupts are just exceptions:
try:
while True:
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
except KeyboardInterrupt:
print('interrupted!')
Then you can exit the loop with CTRL-C.
Answer from Jess on Stack OverflowIf I have a while loop, lest say this one:
while True:
print("a")
time.sleep(3)
if keyboard.is_pressed('q'):
breakThe code only stops when I press 'q' after the previous code is finished. Is there a way to modify the loop so that it can be instantly interrupted regardless of which part of the code is being executed? I want the loop to break immediately upon pressing 'q' without waiting for the sleep period to finish.
Thanks in advance!
You can try wrapping that code in a try/except block, because keyboard interrupts are just exceptions:
try:
while True:
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
except KeyboardInterrupt:
print('interrupted!')
Then you can exit the loop with CTRL-C.
You could use exceptions. But you only should use exceptions for stuff that isn't supposed to happen. So not for this.
That is why I recommand signals:
import sys, signal
def signal_handler(signal, frame):
print("\nprogram exiting gracefully")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
you should put this on the beginning of your program and when you press ctrl+c wherever in your program it will shut down gracefully
Code explanation:
You import sys and signals.
Then you make a function that executes on exit. sys.exit(0) stops the programming with exit code 0 (the code that says, everything went good).
When the program get the SIGINT either by ctrl-c or by a kill command in the terminal you program will shutdown gracefully.
Unable to quit infinite while loop in idle 3.12.0 (64 bit) with keyboard interrupt
Python: how to interrupt, then return to while loop, without goto? - Stack Overflow
python - How to interrupt a while loop with a function - Stack Overflow
python - How to interrupt a while loop, run a function and go back to the loop - Stack Overflow
As long as you're okay with restarting "from the top" after each interrupt (as opposed to returning to the exact point in the loop when the signal was raised, which is a much harder problem):
while True:
try:
controller.main_loop()
except KeyboardInterrupt:
controller.set_coefficients()
In case you don't want a separate thread for IO, generators may be used to preserve the state of your loop across KeyboardInterrupts.
some_parameter = 1
def do_pid_stuff():
while True:
sensor_data1 = 'data'
sensor_data2 = 'data'
sensor_data3 = 'data'
yield 'based on sensor_data1 ' * some_parameter
yield 'based on sensor_data2 ' * some_parameter
yield 'based on sensor_data3 ' * some_parameter
stuff = do_pid_stuff()
while True:
try:
for control_signal in stuff:
print(control_signal)
except KeyboardInterrupt:
some_parameter = int(input())
So the main loop will continue with new parameters from the last executed yield. This however would require to rewrite your loop. Probably, it should be splitted into a generator that will give you sensor data and into a function that will actually do stuff based on the sensor values.
A way to clean up the use of CTRL-C is to use try-except to catch the KeyboardInterrupt like:
try:
while True:
...
...
except KeyboardInterrupt:
exit
The last three lines I added will allow you to break out of the loop with any key being pressed. Dont forget the import of msvcrt
import time, win32api
import msvcrt
cursorX = 0
cursorY = 0
while True:
cursorX, cursorY = win32api.GetCursorPos()
time.sleep(600)
cursorX = cursorX + 10
win32api.SetCursorPos((cursorX,cursorY))
cursorX, cursorY = win32api.GetCursorPos()
time.sleep(600)
cursorX = cursorX - 10
win32api.SetCursorPos((cursorX,cursorY))
if msvcrt.kbhit():
if ord(msvcrt.getch()) != None:
break
The easiest way is to just interrupt it with the usual Ctrl-C (SIGINT).
try:
while True:
do_something()
except KeyboardInterrupt:
pass
Since Ctrl-C causes KeyboardInterrupt to be raised, just catch it outside the loop and ignore it.
There is a solution that requires no non-standard modules and is 100% transportable:
import _thread
def input_thread(a_list):
raw_input() # use input() in Python3
a_list.append(True)
def do_stuff():
a_list = []
_thread.start_new_thread(input_thread, (a_list,))
while not a_list:
stuff()
Hey!
I wanna do the following thing in Python and I'm not very familiar with the multithreading in it.
Basically, I want a separate thread for an event loop that can both a) step on demand b) wait indefinitely and continue on demand c) exit on demand.
With pseudo code:
My main program would look like this
worker = MyClassThatDoesSomeShit()
t = Thread(target=function_that_can_do_what_i_want, args=(worker,))
while True:
text = input()
if text == "step":
t.interrupt_and_skip_to_next_step()
elif text == "wait":
t.interrupt_and_wait_for_continuation()
elif text == "continue":
t.step_and_continue_event_loop()
elif text == "exit":
t.terminate action()And the other half could look something like this:
while not terminated:
try:
worker.do_something()
sleep(some seconds)
except InterruptedException of type "step":
pass
except InterruptedException of type "wait":
try:
sleep(forever)
except InterruptedException of type "continue":
pass
except InterruptedException of type "exit":
breakI would just need a bit of help, because I don't know how this all works in Python.
Thank you!