[pyar] Leer teclado sin bloquear el proceso

1,267 views
Skip to first unread message

Jose Luis Dallapiccola

unread,
Aug 11, 2010, 8:04:07 PM8/11/10
to Python Argentina
Hola, muy buenas noches para todos.

Estoy necesitando resolver la siguiente situación:

Tengo un bucle while y, dentro de ahí, necesito saber si se ha pulsado
alguna tecla, pero sin detener la ejecución del bucle.
Es esto posible? El caso sería similar al siguiente:

##### INICIO

# Estoy leyendo un puerto serie
datos = []
continuar = True
while continuar:
if ser.inWaiting() > 0:
linea = ser.readline().rstrip()

if linea:
datos.append(linea)

# Aca tendria que ir el código para que cuando se detecte la
presión de la tecla "-" (por ejemplo) se salga del bucle
if TeclaPresionada() == "-":
print "Captura finalizada."
continuar = False

print "Datos capturados:"
print datos

##### FIN

No he encontrado con qué función reemplazar TeclaPresionada. Alguna
recomendación?

Desde ya muchísimas gracias a todos.


--
---
José Luis DALLAPICCOLA
Neuquén Capital
Patagonia Argentina
_______________________________________________
pyar mailing list py...@python.org.ar
http://listas.python.org.ar/listinfo/pyar

PyAr - Python Argentina - Sitio web: http://www.python.org.ar/

Ramiro Morales

unread,
Aug 11, 2010, 8:09:35 PM8/11/10
to Python Argentina
2010/8/11 Jose Luis Dallapiccola <jld...@gmail.com>:

> Hola, muy buenas noches para todos.
>
> Estoy necesitando resolver la siguiente situación:
>
> Tengo un bucle while y, dentro de ahí, necesito saber si se ha pulsado
> alguna tecla, pero sin detener la ejecución del bucle.

si estas en windows podes usar msvcrt.kbhit()

Habria que ver en otras plataformas qu€ es lo que hay disponible.

--
Ramiro Morales  |  http://rmorales.net

Ivan Alejandro

unread,
Aug 11, 2010, 8:32:36 PM8/11/10
to Python Argentina
2010/8/11 Jose Luis Dallapiccola <jld...@gmail.com>:
Busca en google cosas como: keyboard read non blocking python

De lo que lei podes usar msvcrt (en win$) y select (en linux) o pygame
si queres multiplataforma, aca te paso unos links que explican mejor
esto:

http://stackoverflow.com/questions/292095/polling-the-keyboard-in-python
http://stackoverflow.com/questions/2408560/python-nonblocking-console-input

Sino lo que se me ocurre es que uses threads para la lectura del
puerto, de esta manero no se trabaria (supongo) si pedis algo por
teclado.

Espero que te sirva.
Saludos
--
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

Roberto Alsina

unread,
Aug 11, 2010, 8:45:17 PM8/11/10
to Python Argentina
On Wednesday 11 August 2010 21:04:07 Jose Luis Dallapiccola wrote:
> Hola, muy buenas noches para todos.
>
> Estoy necesitando resolver la siguiente situación:
>
> Tengo un bucle while y, dentro de ahí, necesito saber si se ha pulsado
> alguna tecla, pero sin detener la ejecución del bucle.
> Es esto posible? El caso sería similar al siguiente:

Por supuesto!

Una manera es poner un eventFilter en tu QApplication! Ah? Que? Que no estás
programando con Qt? Y con que estas programando? Haberlo dicho antes! ;-)

Federico Heinz

unread,
Aug 11, 2010, 9:27:20 PM8/11/10
to py...@python.org.ar
Che, dejen de tirarle salvavidas de plomo al pobre José Luis... :-)

Lo que estás buscando se llama "non-blocking IO", y entiendo que el
soporte que tiene fcntl es multiplataforma. La idea es que cuando
llamás a sys.stdin.read() y no hay datos, no se queda esperando.
Para eso podes poner a sys.stdin en non-blocking mode. Queda más o
menos así (aunque no basta con ingresar "-", hay que darle
"-<ENTER>" para que reaccione, seguramente hay que meterle algún
otro flag más):

import fcntl

# hacé que stdin no bloquee
fd = sys.stdin.fileno()
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)

# Estoy leyendo un puerto serie
datos = []
continuar = True

while continuar:
if ser.inWaiting() > 0:
linea = ser.readline().rstrip()

if linea:
datos.append(linea)

# Aca tendria que ir el código para que cuando se detecte la

# presión de la tecla "-" (por ejemplo) se salga del bucle
if sys.stdin.read(1) == "-":


print "Captura finalizada."
continuar = False

print "Datos capturados:"
print datos

_______________________________________________

Roberto Alsina

unread,
Aug 11, 2010, 9:37:54 PM8/11/10
to Python Argentina
On Wednesday 11 August 2010 22:27:20 Federico Heinz wrote:
> Che, dejen de tirarle salvavidas de plomo al pobre José Luis... :-)
>
> Lo que estás buscando se llama "non-blocking IO", y entiendo que el
> soporte que tiene fcntl es multiplataforma.

No, unix-only, segun http://docs.python.org/library/fcntl.html

Hay maneras de resolverlo pero:

1) Hay que decir por lo menos en que plataforma estas
2) Hay por lo menos que decir si estas en una consola, ventana, o que

O si no, te recomiendan usar cosas que no andan en tu sistema operativo ;-)

Jose Luis Dallapiccola

unread,
Aug 11, 2010, 9:41:15 PM8/11/10
to Python Argentina
Hola. Muchas gracias a todos por las pistas.

2010/8/11 Roberto Alsina <ral...@netmanagers.com.ar>:


> On Wednesday 11 August 2010 22:27:20 Federico Heinz wrote:
> Hay maneras de resolverlo pero:
>
> 1) Hay que decir por lo menos en que plataforma estas

Mucha razón, mil perdones.

Desarrollo en Linux (Ubuntu), pero el programa correrá en Windows.

> 2) Hay por lo menos que decir si estas en una consola, ventana, o que

En principio, de no ser necesario, solamente correrá en consola. El
programa en principio solamente lee unos datos del puerto serie y lo
graba en un archivo.

>
> O si no, te recomiendan usar cosas que no andan en tu sistema operativo ;-)
> _______________________________________________
> pyar mailing list py...@python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>

--

---
José Luis DALLAPICCOLA
Neuquén Capital
Patagonia Argentina

Roberto Alsina

unread,
Aug 11, 2010, 9:53:59 PM8/11/10
to Python Argentina
On Wednesday 11 August 2010 22:41:15 Jose Luis Dallapiccola wrote:
> > 1) Hay que decir por lo menos en que plataforma estas
>
> Mucha razón, mil perdones.
>
> Desarrollo en Linux (Ubuntu), pero el programa correrá en Windows.
>
> > 2) Hay por lo menos que decir si estas en una consola, ventana, o que
>
> En principio, de no ser necesario, solamente correrá en consola. El
> programa en principio solamente lee unos datos del puerto serie y lo
> graba en un archivo.

Consola es una de esas cosas en que windows y linux son muy, pero muy
distintos...


Veamos posibilidades...

1) Podes decir "presione enter" en vez de "presione una tecla"?

Si es así, podés hacer dos hilos, uno hace un raw_input y le pasa un flag al
otro (el que lee el puerto serie), el del puerto serie le devuelve los datos
al que estaba en la consola, este los imprime y termina.

2) Si no podes decir "presione enter", lo mismo, pero haciendo un read() sobre
sys.stdin en vez de un raw_input

3) Si no querés tener dos procesos o hilos es un poco más complicado porque la
manera "fácil" de hacerlo en windows es usar algo tipo conio y en linu algo
tipo curses.

4) Si abandonas la idea de hacerlo primero en linux: usa conio:

http://newcenturycomputers.net/projects/wconio.html

En particular, WConio.kbhit()

Federico Heinz

unread,
Aug 11, 2010, 10:18:18 PM8/11/10
to py...@python.org.ar
On 11/08/2010, Roberto Alsina wrote:
> No, unix-only, segun http://docs.python.org/library/fcntl.html

Beh! Las llamadas habituales a fcntl() funcionan bajo Windows en C,
pero no en Python? No me la esperaba.

Fede

Jose Luis Dallapiccola

unread,
Aug 11, 2010, 10:51:25 PM8/11/10
to Python Argentina

Creo que intentaré con ponerle una "capa" de gtk. Comentare luego cómo me fue. Muchas gracias...

El ago 11, 2010 11:20 p.m., "Federico Heinz" <fhe...@vialibre.org.ar> escribió:

On 11/08/2010, Roberto Alsina wrote: > No, unix-only, segun http://docs.python.org/library/fcntl.htm...

Beh! Las llamadas habituales a fcntl() funcionan bajo Windows en C,
pero no en Python? No me la esperaba.

       Fede

_______________________________________________ pyar mailing list py...@python.org.ar http://listas.p...

Reply all
Reply to author
Forward
0 new messages