Resumen de eventos de Qt

El evento de Qt es uno de los mecanismos centrales de todo el marco de Qt y también es relativamente complicado. Se dice que es complicado, más porque involucra muchas funciones, y hay muchos métodos de procesamiento, a veces es difícil para las personas elegir. Ahora resumimos brevemente el mecanismo de eventos en Qt.

Hay muchos tipos de eventos en Qt: eventos de mouse, eventos de teclado, eventos de cambio de tamaño, eventos de movimiento de posición, etc. Cómo manejar estos eventos, en realidad hay dos opciones:

1. Todos los eventos corresponden a una función de procesamiento de eventos. En esta función de procesamiento de eventos, se utiliza una instrucción de rama grande para seleccionar. Su ejemplo representativo es la función WndProc() de la API win32:

LRESULT CALLBACK WndProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam)

En esta función, necesitamos usar la instrucción switch para seleccionar el tipo de parámetro de mensaje para procesar.El código típico es:

switch(message)
{
    case WM_PAINT:
        // ...
        break;
    case WM_DESTROY:
        // ...
        break;
    ...
}

Los beneficios de este artículo, gratis para recibir el paquete de materiales de aprendizaje de desarrollo Qt , video técnico, que incluye (base del lenguaje C ++, introducción a la programación Qt, mecanismo de señal y ranura QT, dibujo de imagen de desarrollo de interfaz QT, red QT, programación de base de datos QT, QT proyecto de combate, QSS, OpenCV, módulo rápido, preguntas de la entrevista, etc.) ↓↓↓↓↓↓Ver abajo↓↓Haga clic en la parte inferior del artículo para recibir la tarifa↓↓

2. Cada evento corresponde a un controlador de eventos. Qt usa tal mecanismo:

  • evento del ratón()
  • evento de pulsación de tecla ()

Qt tiene tantas funciones de manejo de eventos, debe haber un lugar para distribuirlas, de lo contrario, ¿cómo sabe Qt qué evento llamar a qué función de manejo de eventos? La función de distribución es event(). Obviamente, cuando se genera un QMouseEvent, la función event() lo distribuye al controlador de eventos mouseEvent() para su procesamiento.

La función event() tiene dos problemas:

  1. La función event() es una función protegida, lo que significa que si queremos anular event(), debemos heredar una clase existente. Imagínese, mi programa no quiere eventos de mouse en absoluto, y todos los componentes del programa no pueden manejar eventos de mouse.¿Tengo que heredar todos los componentes y reescribir sus funciones event() una por una? Otro problema causado por la función protegida es que si desarrollo en base a una biblioteca de terceros y la otra parte no proporciona el código fuente, solo hay una biblioteca de enlaces y las demás están empaquetadas. ¿Cómo heredo componentes de esta biblioteca?
  2. La función event() tiene cierto control, pero a veces mis necesidades son más restrictivas: quiero que esos componentes no vean dichos eventos en absoluto. Aunque la función event() se puede interceptar, en realidad recibió el objeto QMouseEvent. Ni siquiera puedo hacerlo cobrar. La ventaja de esto es que el sistema simulado no tiene el efecto de ese evento en absoluto, por lo que otros componentes no recibirán este evento en absoluto y no hay necesidad de modificar sus propias funciones de procesamiento de eventos. ¿Qué debemos hacer con esta necesidad?

Estos dos problemas no son manejados por la función event(). Por lo tanto, Qt proporciona otra solución: filtro de eventos. Los filtros de eventos nos dan la posibilidad de eliminar completamente ciertos eventos. Los filtros de eventos se pueden instalar en cualquier tipo de QObject y se puede instalar más de uno. Si desea implementar un filtro de eventos global, puede instalarlo en QApplication o QCoreApplication. Cabe señalar aquí que si usa la función installEventFilter() para instalar un filtro de eventos para un objeto, entonces el filtro de eventos solo es válido para el objeto, y solo los eventos de este objeto deben pasarse a eventFilter() función del filtro de eventos para filtrar, otros objetos no se ven afectados. Si se instala un filtro de eventos para el objeto QApplication, el filtro es válido para todos los objetos del programa y el evento de cualquier objeto se pasa primero a la función eventFilter().

El filtro de eventos puede resolver las dos deficiencias de la función event() que acabamos de proponer: primero, el filtro de eventos no está protegido, por lo que podemos instalar el filtro de eventos en cualquier subclase QObject; segundo, el filtro de eventos recibe el Evento que se procesa antes , si filtramos el evento, el objeto de destino no verá este evento en absoluto.

De hecho, hay otro método que no presentamos. Las llamadas de los eventos Qt finalmente se rastrearán hasta la función QCoreApplication::notify(), por lo que el mayor derecho de control es en realidad reescribir QCoreApplication::notify(). La declaración de esta función es:

virtual bool QCoreApplication::notify ( QObject * receiver, QEvent * event );

Esta función enviará el evento al receptor, es decir, llamar al receptor->evento(evento), y el valor devuelto es el controlador de eventos del receptor. Tenga en cuenta que esta función se llama para cualquier evento en cualquier objeto de cualquier subproceso, por lo que no tiene problemas de subprocesos con filtros de eventos. Sin embargo, no recomendamos hacer esto, porque solo hay una función de notificación () y los filtros de eventos son mucho más flexibles.

Ahora podemos resumir el manejo de eventos de Qt, que en realidad tiene cinco niveles

  1. Reescriba los controladores de eventos como paintEvent() y mousePressEvent(). Esta es la forma más común y simple, y al mismo tiempo la función más simple.
  2. Anula la función event(). La función event() es la entrada de eventos de todos los objetos, implementada en QObject y QWidget, y el valor predeterminado es pasar el evento a una función de procesamiento de eventos específica.
  3. Instale filtros de eventos en objetos específicos. Este filtro solo filtra los eventos recibidos por este objeto.
  4. Instale filtros de eventos en QCoreApplication::instance(). Este filtro filtrará todos los eventos de todos los objetos, por lo que es tan eficaz como la función de notificación(), pero es más flexible porque se pueden instalar varios filtros. El filtro de eventos global ve los eventos del mouse emitidos por los componentes deshabilitados. Hay un problema con los filtros globales: solo se pueden usar en el hilo principal.
  5. Anule la función QCoreApplication::notify(). Este es el más poderoso, brinda control total como el filtro de eventos global y no está limitado por subprocesos. Pero solo uno puede usarse globalmente (porque QCoreApplication es un singleton).

Para comprender mejor la secuencia de llamada de estos varios niveles de procesamiento de eventos, podemos escribir un código de prueba:

class Label : public QWidget
{
public:
    Label()
    {
        installEventFilter(this);
    }

    bool eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == this) {
            if (event->type() == QEvent::MouseButtonPress) {
                qDebug() << "eventFilter";
            }
        }
        return false;
    }

protected:
    void mousePressEvent(QMouseEvent *)
    {
        qDebug() << "mousePressEvent";
    }

    bool event(QEvent *e)
    {
        if (e->type() == QEvent::MouseButtonPress) {
            qDebug() << "event";
        }
        return QWidget::event(e);
    }
};

class EventFilter : public QObject
{
public:
    EventFilter(QObject *watched, QObject *parent = 0) :
        QObject(parent),
        m_watched(watched)
    {
    }

    bool eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == m_watched) {
            if (event->type() == QEvent::MouseButtonPress) {
                qDebug() << "QApplication::eventFilter";
            }
        }
        return false;
    }

private:
    QObject *m_watched;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Label label;
    app.installEventFilter(new EventFilter(&label, &label));
    label.show();
    return app.exec();
}

Podemos ver que la salida después del clic del mouse es:

QApplication::eventFilter 
eventFilter 
event 
mousePressEvent

Entonces, se puede saber que primero se llama al filtro de eventos global, seguido del filtro de eventos en el objeto, seguido de la función event() y, finalmente, el controlador de eventos específico.

Los beneficios de este artículo, gratis para recibir el paquete de materiales de aprendizaje de desarrollo Qt , video técnico, que incluye (base del lenguaje C ++, introducción a la programación Qt, mecanismo de señal y ranura QT, dibujo de imagen de desarrollo de interfaz QT, red QT, programación de base de datos QT, QT proyecto de combate, QSS, OpenCV, módulo rápido, preguntas de la entrevista, etc.) ↓↓↓↓↓↓Ver abajo↓↓Haga clic en la parte inferior del artículo para recibir la tarifa↓↓

Supongo que te gusta

Origin blog.csdn.net/m0_60259116/article/details/128791583
Recomendado
Clasificación