¿Las señales de Qt pueden ser públicas, protegidas o privadas?

4 minutos de lectura

avatar de usuario de anton
antón

¿Las señales de Qt pueden ser públicas, protegidas o privadas? ¿Puedo crear señales internas, que solo se ven dentro de la clase?

Actualizar: Tengo una clase con algunas señales internas. ¿Cómo puedo hacer que esas señales sean invisibles para otras clases (encapsulación y ocultación de información)?

  • Use el patrón PIMPL en ese caso.

    – jue. Thielemann

    21 oct 2020 a las 20:06


Avatar de usuario de Andrei Vlasyuk
Andrei Vlasuk

No. Las señales no pueden ser públicas ni privadas. Las señales Qt son métodos de clase protegidos.

La palabra clave “señales” se define en qobjectdefs.h (línea 69 como para Qt 4.6.1):

#   define signals protected

ACTUALIZAR: las señales son sólo protected hasta e incluyendo todas las versiones menores de Qt 4. Desde Qt 5.0 en adelante, son public. Consulte https://stackoverflow.com/a/19130831.

  • Creo que las señales ahora se consideran public ver aquí stackoverflow.com/questions/19129133/…

    – johnbakers

    2 de octubre de 2013 a las 5:40

  • Parece que puede haber señales privadas: doc.qt.io/qt-5/qstate.html#finished – ¿Cómo se crean?

    – derM

    27 de julio de 2017 a las 14:35

  • El cambio era necesario para hacer uso de la sintaxis de C++11 en connect funciones, donde se proporciona la devolución de llamada a la función en lugar de una señal o ranura con nombre.

    -mip

    24 de julio de 2022 a las 17:19

Avatar de usuario de Frank Osterfeld
franco osterfeld

Una forma común, por ejemplo, vista en kdelibs, es esta:

Q_SIGNALS:
#ifndef Q_MOC_RUN
    private: // don't tell moc, doxygen or kdevelop, but those signals are in fact private
#endif

   void somePrivateSignal();

Esto hace que la señal sea privada, es decir, solo puede ser emitida por la propia clase pero no por sus subclases. Para no hacer que el “privado:” anule Q_SIGNALS (moc no vería somePrivateSignal como señal entonces), está dentro de Q_MOC_RUN, que solo se define cuando se ejecuta moc.

Editar: Este enfoque no funciona para las conexiones de nuevo estilo introducidas con Qt 5 (connect(a, &A::someSignal, b, &B::someSlot)), ya que requieren que la señal sea accesible.

  • No, como “#define Q_SIGNALS protected”, el privado: no tendrá ningún efecto

    – Frank Osterfield

    9 de enero de 2013 a las 22:20

  • Drat. ¿Por qué todo en C++ requiere un hack?

    – weberc2

    24 de junio de 2013 a las 17:34

  • “Este enfoque no funciona para las conexiones de nuevo estilo introducidas con Qt 5” — depende… Si uno solo quiere permitir conectarse a la señal internamente, también (donde la ranura posiblemente podría emitir otra señal pública), entonces esto es ideal — excepto que la sintaxis anterior todavía permitiría conectarse a él…

    – Aconcagua

    9 de febrero de 2018 a las 18:52


Señales fue protected en Qt4, en Qt5 son public. Int Qt5 puedes hacerlos private añadiendo QPrivateSignal como último argumento. Más sobre esto: http://woboq.com/blog/how-qt-signals-slots-work-part2-qt5.html

  • Buen truco: el moc ignora el último elemento en la firma de la señal en caso de que el nombre sea QPrivateSignal

    – jue. Thielemann

    9 de noviembre de 2020 a las 14:56


  • @ Th.Thielemann, de hecho, un truco bastante terrible …

    -mip

    4 de marzo a las 18:52

Las tragamonedas son métodos simples que pueden ser públicos, protegidos o privados.

Como señaló Andrei, las señales son solo una redefinición de protegido, lo que significa que solo pueden ser emitidas por la clase en la que están definidas.

Si desea que una clase emita una señal de otra, debe agregarle un método público (o ranura) como este:

void emitTheSignal(...) {
  emit theSignal(...);
}

Las señales Qt son públicas en el sentido de que cualquier objeto puede conectarse a cualquier señal.

  • también son públicos en el sentido de que cualquier otra clase puede emitirlos, ya que son funciones públicas. esto puede haber cambiado con respecto a versiones anteriores de Qt. ver aquí stackoverflow.com/questions/19129133/…

    – johnbakers

    2 de octubre de 2013 a las 5:41

  • La programación orientada a objetos utiliza la encapsulación para evitar el acceso a métodos y datos internos. En caso de que las señales sean solo para fines internos, también deben ocultarse.

    – jue. Thielemann

    9 de noviembre de 2020 a las 14:51

Avatar de usuario de Nicolas Holthaus
Nicolás Holthaus

Todas las respuestas existentes son incorrectas.

Una señal se puede hacer privada agregando un QPrivateSignal escriba a su definición como el último argumento:

signals:
  
  void mySignal(QPrivateSignal);

QPrivateSignal es una estructura privada creada en cada QObject subclase por el Q_OBJECT macro, por lo que solo puede crear QPrivateSignal objetos en la clase actual.

Técnicamente, la señal aún tiene visibilidad pública, pero solo puede ser emitida por la clase que la creó.

  • también son públicos en el sentido de que cualquier otra clase puede emitirlos, ya que son funciones públicas. esto puede haber cambiado con respecto a versiones anteriores de Qt. ver aquí stackoverflow.com/questions/19129133/…

    – johnbakers

    2 de octubre de 2013 a las 5:41

  • La programación orientada a objetos utiliza la encapsulación para evitar el acceso a métodos y datos internos. En caso de que las señales sean solo para fines internos, también deben ocultarse.

    – jue. Thielemann

    9 de noviembre de 2020 a las 14:51

avatar de usuario de mip
mip

Hoy en día se puede utilizar Q_SIGNAL macro y especificador de acceso C++ normal:

protected:
  Q_SIGNAL void myProtectedSignal();

private:
  Q_SIGNAL void myPrivateSignal();

¿Ha sido útil esta solución?