Mi hermano pequeño recién se está iniciando en la programación y, para su proyecto de la Feria de Ciencias, está haciendo una simulación de una bandada de pájaros en el cielo. Ha escrito la mayor parte de su código y funciona bien, pero los pájaros necesitan moverse. todo momento .
Tkinter, sin embargo, acapara el tiempo de su propio ciclo de eventos, por lo que su código no se ejecutará. Hacer se root.mainloop()
ejecuta, se ejecuta y se sigue ejecutando, y lo único que se ejecuta son los controladores de eventos.
¿Hay alguna manera de que su código se ejecute junto con el bucle principal (sin subprocesos múltiples, es confuso y esto debería mantenerse simple), y si es así, cuál es?
En este momento, se le ocurrió un truco feo, vinculando su move()
función a <b1-motion>
, de modo que mientras mantenga presionado el botón y mueva el mouse, funcione. Pero tiene que haber una forma mejor.
threading
módulo.La solución publicada por Bjorn da como resultado un mensaje "RuntimeError: Calling Tcl from different appartment" en mi computadora (RedHat Enterprise 5, python 2.6.1). Es posible que Bjorn no haya recibido este mensaje, ya que, según un lugar que verifiqué , el manejo incorrecto del subproceso con Tkinter es impredecible y depende de la plataforma.
El problema parece ser que
app.start()
cuenta como una referencia a Tk, ya que la aplicación contiene elementos Tk. Arreglé esto reemplazandoapp.start()
con unself.start()
inside__init__
. También lo hice para que todas las referencias Tk estén dentro de la función que llamamainloop()
o dentro de funciones que son llamadas por la función que llamamainloop()
(esto es aparentemente crítico para evitar el error de "apartamento diferente").Finalmente, agregué un controlador de protocolo con una devolución de llamada, ya que sin esto, el programa sale con un error cuando el usuario cierra la ventana Tk.
El código revisado es el siguiente:
fuente
run
método? Parece que no puedo entender cómo ...__init__(..)
, los almacenaríaself
y los usaría enrun(..)
while app.is_alive(): etc
Al escribir su propio ciclo, como en la simulación (supongo), necesita llamar a la
update
función que hace lo quemainloop
hace: actualiza la ventana con sus cambios, pero lo hace en su ciclo.fuente
task
se llama a cualquier evento , terminará con bucles de eventos anidados, y eso es malo. A menos que comprenda completamente cómo funcionan los bucles de eventos, debe evitar llamarupdate
a toda costa.Otra opción es dejar que tkinter se ejecute en un hilo separado. Una forma de hacerlo es así:
Sin embargo, tenga cuidado, la programación multiproceso es difícil y es muy fácil dispararse a sí mismo en el pie. Por ejemplo, debe tener cuidado cuando cambia las variables miembro de la clase de muestra anterior para no interrumpir con el ciclo de eventos de Tkinter.
fuente
Esta es la primera versión funcional de lo que será un lector de GPS y presentador de datos. tkinter es una cosa muy frágil con muy pocos mensajes de error. No pone cosas y no dice por qué la mayor parte del tiempo. Muy difícil viniendo de un buen desarrollador de formularios WYSIWYG. De todos modos, esto ejecuta una pequeña rutina 10 veces por segundo y presenta la información en un formulario. Me tomó un tiempo hacerlo realidad. Cuando probé un valor de temporizador de 0, el formulario nunca apareció. ¡Me duele la cabeza ahora! 10 o más veces por segundo es suficiente para mí. Espero que ayude a alguien más. Mike Morrow
fuente