tutorial signal custom and c++ qt signals-slots qt-signals

c++ - custom - signals and slots qt



Cuándo usar señales y ranuras y cuándo no (5)

¿Está bien suponer que se manejará una señal?

No, no es. Las señales son cosas que se olvidan y se olvidan. Quién se conecta a una señal y qué hace no debería ser la preocupación del emisor.

Estamos usando Qt que ofrece señales y ranuras que me parecen realmente convenientes. Sin embargo, con un gran poder viene una gran responsabilidad y creo que es muy fácil también hacer un mal uso de esta característica.

¿Hay alguna mejor práctica para el uso de la ranura de señal? Me está costando encontrar algunas pautas generales de esta manera. Algunas preguntas (tengo opiniones claras, pero con las que no todos los miembros de mi equipo están de acuerdo):

  • ¿Está bien usar señales para informar errores?
  • ¿Está bien suponer que se manejará una señal?
  • ¿Se pueden usar señales para iniciar acciones? Por ejemplo signal displayInfoScreen() debe manejarse mediante una ranura que muestre una pantalla de información.

¡Cualquier otra opinión sobre cuándo deberían / ​​no deberían usarse las señales es muy bienvenida!


¿Está bien usar señales para informar
errores?

Sí, por ejemplo, vea QFtp, donde la señal hecha tiene un estado. No lleva el error real, solo la información que ha ocurrido un error.

¿Está bien suponer que se manejará una señal?

No. El remitente nunca puede asumir que, sin embargo, su aplicación particular puede depender de ello. Por ejemplo, la QAction que representa Archivo - Nuevo necesita ser manejada para que la aplicación funcione, pero al objeto QAction no le importaría menos.

¿Se pueden usar señales para iniciar acciones? Por ejemplo, la visualización de la señal InfoScreen () debe manejarse mediante una ranura que muestre una pantalla de información.

De nuevo, sí, por ejemplo, el objeto QAction. Pero si desea poder reutilizar componentes, debe tener cuidado de asegurarse de que la clase real no dependa de ella.


¿Está bien usar señales para informar errores?

Sí, pero generalmente haría que esta situación dependa. Si el error puede ocurrir de manera asíncrona, entonces una señal para indicarlo es definitivamente correcta. Si el error solo ocurre cuando el código del cliente llama a una determinada función, entonces el error debe estar en la respuesta de esa función, no como una señal. Sin embargo, hay una gran variedad de situaciones intermedias que podrían hacerse caso por caso.

Además, los mecanismos de ranura de señal pueden facilitar la comunicación entre hilos (lo que bien podría considerarse el caso asíncrono), y los usaré para ese propósito (error o no).

¿Está bien suponer que se manejará una señal?

Las señales están (filosóficamente) diseñadas para indicar que algo ha sucedido. Como han indicado otros, nunca es una buena idea suponer que una señal se combinará con una ranura, o incluso con una ranura más.

¿Se pueden usar señales para iniciar acciones? Por ejemplo, la visualización de la señal InfoScreen () debe manejarse mediante una ranura que muestre una pantalla de información.

Las señales se pueden usar para iniciar acciones, pero probablemente no de la manera en que estás pensando. La señal indica que foo ha sucedido. Si el código que supervisa a su clase decide que cuando suceda, debe mostrarse un diálogo, luego la señal se utilizó para iniciar esa acción. Sin embargo, generalmente no es responsabilidad de la clase que emite la señal garantizar que se realice la acción adecuada, porque no es responsable de realizar esa acción. (Si lo fuera, entonces debería ser parte de la misma clase, y no se necesitaría ninguna señal).


Las señales / slots (también llamados eventos) son una buena manera de eliminar el acoplamiento entre objetos.

Por ejemplo, en lugar de tener vistas que entienden cómo funciona el modelo, y cuando el modelo cambia, "escuchan" el modelo. El modelo es responsable de decir cuándo cambia, qué cambia.

El problema con los eventos es cuando diseñas tus eventos con los requisitos del cliente. Por ejemplo, no debería tener una señal displayInfoScreen porque asume algo sobre los objetos que usan esta señal. En su lugar, debe ser infoChanged y el InfoScreenDisplayer escucha estas señales para mostrarlo en la pantalla. Si lo necesita, puede agregar luego un InfoTweeterPoster que publique la información en Tweeter cada vez que cambien.


Las señales y las ranuras son potentes porque desacopla objetos. No puede suponer que una señal tiene una ranura conectada, como se respondió previamente.

Un inconveniente importante del diseño basado en señal / ranura es que puede perder fácilmente la lógica que implementó , ya que una acción de un objeto puede desencadenar otras acciones de cualquier otro objeto que se conecte a una señal emitida. Es mucho más fácil tener efectos secundarios no deseados, llamadas recursivas, etc.