views:

656

answers:

2

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?

Thanks in advance.

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

EDIT: I´m on windows.

A: 

You can use select to see if there's any input available on sys.stdin, then use read() to read it in.

Ignacio Vazquez-Abrams
I´m not sure if I understand. Could you please make an example or something?
ImTooStupidForThis
`result = select.select([sys.stdin], [], [], 0.05)``if sys.stdin in result[0]:`` ...`
Ignacio Vazquez-Abrams
Error:result = select.select([sys.stdin], [], [], 0.05)TypeError: argument must be an int, or have a fileno() method.
ImTooStupidForThis
Sounds like something has replaced `sys.stdin` with a file-like instead of a real file.
Ignacio Vazquez-Abrams
sys.stdin sounds sorta like a linux thing. Maybe I should have mentioned Im on windows.
ImTooStupidForThis
Ah, well, like the documentation says, `select` can only be used on sockets in Windows. You'll have to use `msvcrt.kbhit()` instead.
Ignacio Vazquez-Abrams
Uh. Sorry but, could you maybe give me some example code or something? I´m really not getting this. I´m kind of slow without examples. Thanks.
ImTooStupidForThis
+6  A: 

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
mizipzor
I already have pygame, so I will try this out. Thanks.Still, does anyone else have any better solution? I want to keep it a console.
ImTooStupidForThis
Thanks for the msvcrt stuff. You are awesome.
ImTooStupidForThis
Happy to be of assistance, welcome to Stackoverflow. :)
mizipzor