Pause an infinite while loop with a single keypress
Question:
I’m new to python and i have been trying to find a simple way to pause an operating while-loop, making it possible to start it again from where it was paused. I have searched google for help and tips, but everything i find seems very complex. Is there a simple way to do this?
I’ve read that you can use termios and tkinter.
Im using ubuntu.
Sorry for language mistakes
Thanks!
Answers:
Don’t about how to do it with a single keypress, but to resume and pause a while loop you can use generator functions
, see the example below:
i=-1
def infi():
global i
while i<99999999:
i+=1
yield i
a=iter(infi())
for x in range(6):
print(next(a))
#loop paused at 5
print('now it wil start from start 6')
for x in range(11):
print(next(a))
output:
0
1
2
3
4
5
now it wil start from start 6
6
7
8
9
10
11
12
13
14
15
16
Here’s a simple tkinter program that runs in an infinite loop. Pressing space pauses/unpauses it, and pressing Esc quits.
Note: The following is for Python 2.x, if you’re using Python 3, change Tkinter
in the first line to tkinter
(lower case t).
from Tkinter import *
import time
class MyLoop():
def __init__(self, root):
self.running = True
self.aboutToQuit = False
self.root = root
self.someVar = 0
self.root.bind("<space>", self.switch)
self.root.bind("<Escape>", self.exit)
while not self.aboutToQuit:
self.root.update() # always process new events
if self.running:
# do stuff
self.someVar += 1
print(self.someVar)
time.sleep(.1)
else: # If paused, don't do anything
time.sleep(.1)
def switch(self, event):
print(['Unpausing','Pausing'][self.running])
self.running = not(self.running)
def exit(self, event):
self.aboutToQuit = True
self.root.destroy()
if __name__ == "__main__":
root = Tk()
root.withdraw() # don't show the tkinter window
MyLoop(root)
root.mainloop()
This is a possible output, where I manually paused and unpaused the program twice before I quit.
1
2
3
4
5
6
7
Pausing
Unpausing
8
9
10
11
12
13
14
15
16
Pausing
Unpausing
17
18
19
20
21
22
23
24
25
dude it’s a while loop… don’t run it in a while loop, that will block up the CPU, just try using timers…
Here is a python 3 example of getting input from a window that is not displayed, tested on OSX, Linux Ubuntu and Windows 8
import tkinter as tk
import time
class App():
def __init__(self):
self.state = 'running'
self.cnt = 0
self.root = tk.Tk()
self.update_clock()
self.root.bind("<Key>", self.key)
self.root.geometry('1x1+9000+9000')
self.root.mainloop()
def update_clock(self):
now = time.strftime("%H:%M:%S")
self.root.after(100, self.update_clock)
self.root.focus_set()
if(self.state == 'running'):
self.cnt = self.cnt + 1
if(self.cnt <= 100):
print('state: ',self.state,' count:',self.cnt,'%')
else:
exit()
def key(self,event):
self.root.focus_force()
if(event.keysym == 'Escape'):
self.state = 'paused'
elif(event.keysym == 'space'):
self.state = 'running'
print("pressed", repr(event.keysym))
print("state",self.state)
app=App()
app.mainloop()
You can thank @saranyan for this…
I searched forever for this solution, but it turned out to be really simple. I’m pretty the select module only works on Unix systems, but it made things really easy.
import sys
import select
inputSrc = [sys.stdin]
while True:
# Do important stuff
# Check if a key was pressed and if so, process input
keypress = select.select(inputSrc, [], [], 0)[0]
while keypress:
for src in keypress:
line = src.readline()
if not line:
inputSrc.remove(src)
else:
# The "enter" key prints out a menu
if line == "n":
print "Test PausednOptions: [0]: Quit [any other key]: Resume"
elif line.rstrip() == "0":
exit(0)
elif len(line) >= 1: #any other key
print "Resuming..."
keypress = None
If you’re running on Windows and you want to perform a single keypress (so without typing the whole "pause" word), you can do something like:
import msvcrt
import sys
KEY_CODE = 32 # 32 is the ASCII code for space
while condition:
# do something
if msvcrt.kbhit() and ord(msvcrt.getch()) == KEY_CODE:
input("n[PAUSED] Press Enter to continue:")
I’m new to python and i have been trying to find a simple way to pause an operating while-loop, making it possible to start it again from where it was paused. I have searched google for help and tips, but everything i find seems very complex. Is there a simple way to do this?
I’ve read that you can use termios and tkinter.
Im using ubuntu.
Sorry for language mistakes
Thanks!
Don’t about how to do it with a single keypress, but to resume and pause a while loop you can use generator functions
, see the example below:
i=-1
def infi():
global i
while i<99999999:
i+=1
yield i
a=iter(infi())
for x in range(6):
print(next(a))
#loop paused at 5
print('now it wil start from start 6')
for x in range(11):
print(next(a))
output:
0
1
2
3
4
5
now it wil start from start 6
6
7
8
9
10
11
12
13
14
15
16
Here’s a simple tkinter program that runs in an infinite loop. Pressing space pauses/unpauses it, and pressing Esc quits.
Note: The following is for Python 2.x, if you’re using Python 3, change Tkinter
in the first line to tkinter
(lower case t).
from Tkinter import *
import time
class MyLoop():
def __init__(self, root):
self.running = True
self.aboutToQuit = False
self.root = root
self.someVar = 0
self.root.bind("<space>", self.switch)
self.root.bind("<Escape>", self.exit)
while not self.aboutToQuit:
self.root.update() # always process new events
if self.running:
# do stuff
self.someVar += 1
print(self.someVar)
time.sleep(.1)
else: # If paused, don't do anything
time.sleep(.1)
def switch(self, event):
print(['Unpausing','Pausing'][self.running])
self.running = not(self.running)
def exit(self, event):
self.aboutToQuit = True
self.root.destroy()
if __name__ == "__main__":
root = Tk()
root.withdraw() # don't show the tkinter window
MyLoop(root)
root.mainloop()
This is a possible output, where I manually paused and unpaused the program twice before I quit.
1
2
3
4
5
6
7
Pausing
Unpausing
8
9
10
11
12
13
14
15
16
Pausing
Unpausing
17
18
19
20
21
22
23
24
25
dude it’s a while loop… don’t run it in a while loop, that will block up the CPU, just try using timers…
Here is a python 3 example of getting input from a window that is not displayed, tested on OSX, Linux Ubuntu and Windows 8
import tkinter as tk
import time
class App():
def __init__(self):
self.state = 'running'
self.cnt = 0
self.root = tk.Tk()
self.update_clock()
self.root.bind("<Key>", self.key)
self.root.geometry('1x1+9000+9000')
self.root.mainloop()
def update_clock(self):
now = time.strftime("%H:%M:%S")
self.root.after(100, self.update_clock)
self.root.focus_set()
if(self.state == 'running'):
self.cnt = self.cnt + 1
if(self.cnt <= 100):
print('state: ',self.state,' count:',self.cnt,'%')
else:
exit()
def key(self,event):
self.root.focus_force()
if(event.keysym == 'Escape'):
self.state = 'paused'
elif(event.keysym == 'space'):
self.state = 'running'
print("pressed", repr(event.keysym))
print("state",self.state)
app=App()
app.mainloop()
You can thank @saranyan for this…
I searched forever for this solution, but it turned out to be really simple. I’m pretty the select module only works on Unix systems, but it made things really easy.
import sys
import select
inputSrc = [sys.stdin]
while True:
# Do important stuff
# Check if a key was pressed and if so, process input
keypress = select.select(inputSrc, [], [], 0)[0]
while keypress:
for src in keypress:
line = src.readline()
if not line:
inputSrc.remove(src)
else:
# The "enter" key prints out a menu
if line == "n":
print "Test PausednOptions: [0]: Quit [any other key]: Resume"
elif line.rstrip() == "0":
exit(0)
elif len(line) >= 1: #any other key
print "Resuming..."
keypress = None
If you’re running on Windows and you want to perform a single keypress (so without typing the whole "pause" word), you can do something like:
import msvcrt
import sys
KEY_CODE = 32 # 32 is the ASCII code for space
while condition:
# do something
if msvcrt.kbhit() and ord(msvcrt.getch()) == KEY_CODE:
input("n[PAUSED] Press Enter to continue:")