yoast una título titulo que name keywords etiquetas etiqueta description descripción descripcion qt events filter meta qevent

qt - una - ¿Para qué sirve QMetaCallEvent y cómo acceder a sus detalles?



titulo seo yoast (3)

El QEvent::MetaCall - QEvent::MetaCall se crea cada vez que se emite una señal que está conectada a una ranura en el QObject receptor. Reaccionar a este evento en un controlador de evento / filtro personalizado parece eludir la característica más poderosa de Qt, la arquitectura de ranura de señal. Probablemente sea mejor averiguar a qué ranura se llama y si esa ranura es virtual, por lo que puede sobrecargarla.

Tengo un filtro de eventos y me di cuenta cuando hago clic para expandir / colapsar una rama de árbol, obtengo QEvent::MetaCall . Estaba pensando en usar esto para rodar mi propio código de expandir / colapsar, pero no sé cómo obtener información, como el índice del artículo.

¿Hay algo disponible en este tipo de evento MetaCall?

Encontré que alguien había hecho esta misma pregunta en otro sitio, pero sin una respuesta, aquí: http://www.qtcentre.org/threads/37525-How-to-filter-QEvent-MetaCall

¿Para qué se usa típicamente este evento?


La pregunta más importante es: ¿qué estás tratando de hacer exactamente? ¿Cuál es la clase Qt que recibió esos eventos? En lo que a mí respecta, estás tratando de hacer las cosas de la manera más difícil, así que ¿para qué molestarse?

QMetaCallEvent es el evento que representa una llamada de ranura cada vez que se utiliza una conexión en cola para invocar una ranura. Esto podría deberse a un disparo de señal que estaba conectado a una ranura, o debido al uso de QMetaObject::invoke QMetaObject::invokeMethod o QMetaObject::invokeMethod . ¡El bit de conexión en cola es la parte importante! Las conexiones en cola no se usan por defecto, ya que tienen la sobrecarga de administración de colas de eventos, a menos que una de las dos condiciones siguientes sea verdadera:

  1. Proporciona el argumento Qt::QueuedConnection para QObject::connect o QMetaObject::invoke[Method] , o

  2. El thread() del objeto receptor thread() es diferente del subproceso donde se origina la llamada.

La clase de evento QMetaCallEvent contiene la información necesaria para invocar un espacio. Contiene el QObject emisor y su identificación de señal (si la llamada proviene de una conexión de ranura de señal), así como también el identificador de ranura de destino y los argumentos necesarios para pasar a la ranura.

Por lo tanto, podría verificar si la ranura llamada es la que desea interceptar, así como también qué argumentos le fueron pasados. Por ejemplo, si llama a una ranura con un solo parámetro int , entonces *reinterpret_cast<int*>(metaCallEvent->args()[1]) le dará el valor de ese entero. El argumento zero-th se usa para el valor de retorno, si lo hay, de modo que los parámetros se indexan con base 1.

Descargo de responsabilidad Dado que la clase QMetaCallEvent es interna para la implementación de Qt, está haciendo que el binario de la aplicación esté vinculado a la versión particular de Qt en su totalidad (versión major.minor completa) y usted pierde los beneficios de la compatibilidad binaria ofrecida por Qt en la versión principal. ¡Su código aún puede compilarse, pero dejará de funcionar correctamente cuando cambie a otra versión menor de Qt!

Lo que sigue se aplica a Qt 5.2.0, ¡no he visto ninguna otra versión!

Entonces, supongamos que quiere interceptar una llamada a QLabel::setNum . Podrías atrapar tales eventos de la siguiente manera:

#include <private/qobject_p.h> // Declaration of QMetaCallEvent bool Object::eventFilter(QObject * watched, QEvent * event) { QLabel * label = qobject_cast<QLabel*>(watched); if (! label || event->type() != QEvent::MetaCall) return false; QMetaCallEvent * mev = static_cast<QMetaCallEvent*>(event); static int setNumIdx = QLabel::staticMetaObject.indexOfSlot("setNum(int)"); if (mev->id() != setNumIdx) return false; int num = *reinterpret_cast<int*>(mev->args()[1]); // At this point, we can invoke setNum ourselves and discard the event label->setNum(num); return true; }

Si desea ver, globalmente, todas las máquinas tragamonedas que se llaman utilizando el sistema metacall, puede hacerlo también. La parametrización de la plantilla de la clase base permite flexibilidad para usar cualquier clase de aplicación, digamos QCoreApplication , QGuiApplication , QApplication o un tipo derivado por el usuario.

template <class Base> class MetaCallWatcher : public Base { MetaCallWatcher(int& argc, char** argv) : Base(argc, argv) {} bool notify(QObject * receiver, QEvent * event) { if (event->type() == QEvent::MetaCall) { QMetaCallEvent * mev = static_cast<QMetaCallEvent*>(event); QMetaMethod slot = receiver->metaObject()->method(mev->id()); qDebug() << "Metacall:" << receiver << slot.methodSignature(); } return Base::notify(receiver, event); } } int main(int argc, char ** argv) { MetaCallWatcher<QApplication> app(argc, argv); ... }


QEvent::MetaCall se usa para entregar señales de cruce de hilos.