Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking console input?

I am trying to make a simple IRC client in Python (as kind of a project while I learn the language).

I have a loop that I use to receive and parse what the IRC server sends me, but if I use raw_input to input stuff, it stops the loop dead in its tracks until I input something (obviously).

How can I input something without the loop stopping?

(I don't think I need to post the code, I just want to input something without the while 1: loop stopping.)

I'm on Windows.

like image 668
ImTooStupidForThis Avatar asked Mar 09 '10 11:03

ImTooStupidForThis


1 Answers

For Windows, console only, use the msvcrt module:

import msvcrt  num = 0 done = False while not done:     print(num)     num += 1      if msvcrt.kbhit():         print "you pressed",msvcrt.getch(),"so now i will quit"         done = True 

For Linux, this article describes the following solution, it requires the termios module:

import sys import select import tty import termios  def isData():     return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])  old_settings = termios.tcgetattr(sys.stdin) try:     tty.setcbreak(sys.stdin.fileno())      i = 0     while 1:         print(i)         i += 1          if isData():             c = sys.stdin.read(1)             if c == '\x1b':         # x1b is ESC                 break  finally:     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) 

For cross platform, or in case you want a GUI as well, you can use Pygame:

import pygame from pygame.locals import *  def display(str):     text = font.render(str, True, (255, 255, 255), (159, 182, 205))     textRect = text.get_rect()     textRect.centerx = screen.get_rect().centerx     textRect.centery = screen.get_rect().centery      screen.blit(text, textRect)     pygame.display.update()  pygame.init() screen = pygame.display.set_mode( (640,480) ) pygame.display.set_caption('Python numbers') screen.fill((159, 182, 205))  font = pygame.font.Font(None, 17)  num = 0 done = False while not done:     display( str(num) )     num += 1      pygame.event.pump()     keys = pygame.key.get_pressed()     if keys[K_ESCAPE]:         done = True 
like image 144
Mizipzor Avatar answered Sep 29 '22 07:09

Mizipzor