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!

Asked By: fatninja

||

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
Answered By: Ashwini Chaudhary

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
Answered By: Junuxx

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
Answered By: agruwell

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:")
Answered By: horcrux