Pregunta

wx (y wxPython) tiene dos eventos que extraño en PyQt:

  • EVT_IDLE que se está enviando a un marco. Se puede utilizar para actualizar los diversos widgets según el estado de la aplicación
  • EVT_UPDATE_UI que se envía a un widget cuando debe ser repintado y actualizado, por lo que puedo calcular su estado en el controlador

Ahora, PyQt no parece tener estos, y el libro de PyQt sugiere escribir un método updateUi y llamarlo manualmente. Incluso terminé llamándolo desde un temporizador una vez cada 0.1 segundos, para evitar muchas llamadas manuales de métodos que pueden actualizar la GUI. ¿Me estoy perdiendo de algo? ¿Hay una mejor manera de lograr esto?


Un ejemplo: tengo una aplicación simple con un botón de Inicio que inicia un procesamiento. El botón de inicio debe habilitarse solo cuando un archivo se ha abierto con el menú. Además, hay un widget permanente en la barra de estado que muestra información.

Mi aplicación tiene estados:

  1. Antes de abrir el archivo (en este estado, la barra de estado muestra algo especial y el botón de inicio está deshabilitado)
  2. El archivo se abrió y el procesamiento no se inició: el botón de inicio está habilitado, la barra de estado muestra algo más
  3. El procesamiento se está ejecutando: el botón de inicio ahora dice " Detener " ;, y la barra de estado informa del progreso

En Wx, tendría el evento de actualización de la interfaz de usuario del botón que controla su estado: el texto que contiene y si está habilitado, dependiendo del estado de la aplicación. Lo mismo para la barra de estado (o usaría EVT_IDLE para eso).

En Qt, tengo que actualizar el botón en varios métodos que pueden afectar el estado, o simplemente crear un método update_ui y llamarlo periódicamente en un temporizador. ¿Cuál es la forma más " QT " -ish?

¿Fue útil?

Solución

El uso de EVT_UPDATE_UI en wxWidgets parece resaltar una de las diferencias fundamentales en la forma en que wxWidgets y Qt esperan que los desarrolladores manejen eventos en su código.

Con Qt, conecta señales y ranuras entre widgets en la interfaz de usuario, ya sea manejando " lógica de negocios " en cada slot o delegándolo a un método dedicado. Por lo general, no se preocupa por realizar cambios separados en cada widget en su GUI porque las solicitudes de repintado se colocarán en la cola de eventos y se entregarán cuando el control regrese al bucle de eventos. Algunos eventos de pintura pueden incluso fusionarse por razones de eficiencia.

Por lo tanto, en una aplicación Qt normal donde las señales y las ranuras se usan para manejar los cambios de estado, básicamente no hay necesidad de tener un mecanismo inactivo que supervise el estado de la aplicación y actualice los widgets, ya que esas actualizaciones deberían ocurrir automáticamente.

Tendría que decir un poco más sobre lo que está haciendo para explicar por qué necesita un equivalente a este evento en Qt.

Otros consejos

Enviaría señales Qt para indicar cambios de estado (por ejemplo, FileOpened, processingStarted, processingDone). Las ranuras en los objetos que administran el botón de inicio y el widget de la barra de estado (o subclases) pueden conectarse a esas señales, en lugar de " sondeo " para el estado actual en un evento inactivo.

Si desea que la señal se aplace más adelante en el bucle de eventos en lugar de hacerlo inmediatamente (por ejemplo, porque va a tomar un poco de tiempo para hacer algo), puede usar un " en cola " Conexión de ranura de señal en lugar de la normal.

http://doc.trolltech.com/4.5/signalsandslots.html#signals

El tipo de conexión es un parámetro opcional para la función connect (): http://doc.trolltech.com/4.5/qobject.html#connect, http://doc.trolltech.com/4.5/qt.html# ConnectionType-enum

Según tengo entendido, EVT_IDLE se envía cuando la cola de mensajes de la aplicación está vacía. No existe tal evento en Qt, pero si necesita ejecutar algo en Qt cuando no hay eventos pendientes, debe usar QTimer con 0 tiempo de espera.

En general, la forma más rápida de Qt-ish es actualizar el botón / barra de herramientas según sea necesario en cualquier función que requiera la actualización, o consolidar parte de la funcionalidad y llamar directamente a esa función cuando el programa lo necesite (como una actualización). función).

Debe tener en cuenta que en Qt, el cambio de un atributo de un elemento Ui no causa un redibujado inmediato, sino que pone en cola un redibujado en el sistema de eventos, y varias llamadas de redibujado se comprimen en uno siempre que sea posible.

En cuanto a los múltiples cambios relacionados con el estado, eche un vistazo a esta publicación de blog acerca de una futura incorporación a Qt para manejar los estados con mayor facilidad. Parece que esto se encargaría de muchas de sus quejas, porque en sus múltiples funciones, simplemente podría hacer la transición de la variable de estado, y las otras partes de la interfaz de usuario deberían actualizarse para coincidir. No es positivo que esto llegue al próximo lanzamiento de Qt (aunque apostaría por él, o algo similar), y no tengo idea de qué tan cerca PyQt rastrea los lanzamientos de Qt. O alternativamente, puede usar el concepto y crear su propia clase para rastrear el estado según sea necesario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top