c++ - signal - Qt señales y ranuras: permisos
signals and slots qt (3)
- Las señales están protegidas en Qt4 pero son públicas en Qt5, por lo tanto, la información contradictoria.
- Las máquinas tragamonedas son funciones y se respeta lo público / protegido / privado al llamarlas como tales, cuando se conecta a una señal, el sistema de metaobjetos lo ignora.
- Como las
signals
se definen comopublic:
anteponiéndolas, por ejemplo, con clientes potenciales privados
a:
private:
public: //signals:
void theSignal();
Por lo tanto, es sin efecto.
- Todas las clases se pueden conectar a cualquier señal, correcto. Las señales son parte de la API pública en ese sentido.
- Tener firmas de señal idénticas no es un problema. El contexto está definido por el objeto especificado como remitente.
Usando el viejo estilo de conexión:
Apple *apple ... Orange* orange
connect(apple, SIGNAL(changed()), this, SLOT(appleChanged()));
connect(orange, SIGNAL(changed()), this, SLOT(orangeChanged()));
La señal se especifica como una cadena aquí (sin el nombre de clase), pero como apple
y orange
tienen una sola señal changed()
cada una y la búsqueda se realiza en el metaobjeto de la instancia de QObject, que existe una por clase (no instancia ), no pueden colisionar.
Versión Qt 5 con comprobación en tiempo de compilación:
connect(apple, &Apple::changed, this, &MyReceiver::appleChanged);
Aquí uno debe especificar una función, por lo que dependiendo del alcance, uno debe especificar un nombre de clase (y tal vez espacios de nombres). Como un nombre de función ambiguo no sería válido en C ++ y, por lo tanto, no se compilaría, por lo tanto, aquí es seguro.
Hay discrepancias entre las respuestas respetadas aquí en SO y los documentos de Qt reales.
He leído esta pregunta y quiero más aclaraciones. ¿Alguien puede confirmar?
- Una señal siempre está
protected
, por lo tanto, solo puede ser emitida por la clase o cualquiera de sus subclases. No estoy seguro de que esto sea cierto; la pregunta anterior muestra las respuestas que respaldan esta afirmación. Pero los documentos de Qt dicen: lasSignals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses.
Entonces, ¿cuál es? - Las máquinas tragamonedas son solo funciones y, por lo tanto, pueden ser públicas, privadas o estar protegidas. Obviamente, una clase externa tendrá la capacidad de controlar si su clase conecta una de sus propias señales a una de sus propias máquinas tragamonedas si la ranura es pública. Sin embargo, una vez más, la información SO difiere de los documentos, que dicen:
a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.
Esto significa queprivate
no es honrado por el mecanismo de señal / ranura? - Las palabras público, privado, protegido no tienen uso para trabajar con la palabra clave de
signal
- La señal emitida siempre está disponible para todas las demás clases, es decir, cualquier otra clase siempre se puede conectar a esa señal (independientemente de su permiso para emitir la señal).
- A pesar de que todas las señales son visibles para todas las clases, aún podría tener dos clases con señales del mismo nombre, ya que la función de
connect
toma el nombre de clase como un prefijo de señal (es decir,SomeClass::itsSignal
)
Eche un vistazo a qobjectdefs.h
(QT5.0 +). Allí se definen las macros moc
# define signals public
Como puede ver, las macros utilizadas en los archivos de encabezado para las señales se definen como públicas. En cuanto a las directivas estatales, privadas y protegidas explícitas, estas se ignoran en la sección de señales. Las versiones anteriores de QT tienen señales definidas como protegidas. Esos todavía estaban disponibles para conexiones utilizando la macro SIGNAL()
.
Las ranuras macro
# define slots
se define como una macro vacía y, por lo tanto, se puede usar con:
public slots:
private slots:
protected slots:
La visibilidad del método se usa para llamadas a métodos directos, por lo que no se puede llamar a privado / protegido desde clases extranjeras directamente.
El uso de la declaración a connect
aún funciona independientemente de la visibilidad. Este es el comportamiento previsto y se implementa en el código generado por moc.
Si recuerdo correctamente en versiones anteriores de Qt, una ranura también era public
automáticamente, pero no encontré una referencia para eso ahora.
Cualquier otra clase puede conectarse a una señal de una clase extranjera, siempre que la macro Q_OBJECT esté dada en la clase y la clase extranjera sea conocida (encabezado incluido). Como las señales se definen por clase, es perfectamente legal tener la misma señal en diferentes clases. Esto también es muy conveniente, por ejemplo, tener una señal sendInfo (QString) en todas las clases hace que sea más fácil de recordar. La macro Q_OBJECT hace que el moc cree el código necesario para conectar las señales a las ranuras independientemente de la visibilidad.
La señal emitida siempre está disponible para todas las demás clases, es decir, cualquier otra clase siempre se puede conectar a esa señal (independientemente de su permiso para emitir la señal).
En Qt5, esto no es necesariamente cierto. Se puede definir una señal con QPrivateSignal
como su argumento final, y en ese caso, solo el objeto que declaró la señal podría conectarse a él.