mecanismo Qt bucle de eventos

Original: https://blog.csdn.net/simonyucsdy/article/details/82749539

Pregunta 1: Qt evento común ¿Qué?

R: Los eventos de ratón (QMouseEvent), eventos de teclado (QKeyEvent), dibujar evento (QPaintEvent), cambio de tamaño de la ventana (QResizeEvent), eventos de desplazamiento (QScrollEvent), pantallas de control (QShowEvent), controles ocultos (QHideEvent), el evento de temporizador (QTimerEvent ) y así sucesivamente. .

Pregunta 2: Qt es dirigido por eventos, cómo entender que esta frase?

Qt convierte la señal (interrupción de software) generado por el sistema para eventos QT, y eventos empaquetado como tales, todas las clases de eventos se derivan de la QEvent, la producción de eventos y el procesamiento es el programa Qt husillo, y junto con el programa entero ciclo de funcionamiento. Por eso decimos, Qt es por eventos.

Pregunta 3: Qt evento se genera por quién? Qt es cómo la señal se convierte en un evento?

A: El manual oficial de Qt dijo que el incidente de dos fuentes: los programas externos y procedimientos internos, en la mayoría de los casos desde el sistema operativo y la función devuelve True de hecho espontáneo () para aprender de programas externos, lo que indica cuando la espontánea () devuelve false eventos desde dentro del programa, al igual que las rutinas de 1 crear un evento y distribuirlo a cabo.

Pregunta 4: Qt evento es recibido por quién?

R: QObject! Es la clase base para todas las clases de Qt! Qt es el modelo de objetos de núcleo! Una de las tres funciones básicas que clase QObject es: procesamiento de eventos. QObject por evento de llamada () para obtener el evento. Todas las clases necesarias para controlar el evento debe heredar de QObject, puede ser función de re-definido evento () para implementar un controlador de eventos personalizado o evento a los padres.

Pregunta 5: Proceso de manejo de eventos es lo que?

A: El punto importante es diferente del caso de la señal: el evento es un objeto de la clase tiene un tipo específico, en un evento en la mayoría de los casos se distribuye a una cola (cola de eventos), cuando hay una cola de eventos sin parar en la cola el evento se envía al objeto QObject, cuando la cola está vacía cuando está bloqueado a la espera de un evento, este proceso es el bucle de eventos !

QCoreApplication :: exec () abre este ciclo hasta QCoreApplication :: salida () es llamado antes de la terminación, para que Qt bucle de eventos se acompaña de un programa de todo el ciclo de funcionamiento!

Otro caso es el procesamiento de sincronización () para enviar eventos a través de sendEvent a cabo, y el procesamiento de flujo directamente en el evento de transferencia.

El procesamiento de eventos es como se muestra:

img

Rutina 1: Distribución de evento sincronizado sendEvent

/*!
 * \brief Widget::Widget 使用sendEvent同步分发事件
 * 使用QPushButton模拟键盘的回删和向前删除按键
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_button_back_clicked()
{
    int key = Qt::Key_Backspace; //
 
    QKeyEvent EventPress(QEvent::KeyPress, key, Qt::NoModifier);
    QApplication::sendEvent(ui->textEdit, &EventPress);
 
    QKeyEvent EventRelease(QEvent::KeyRelease, key, Qt::NoModifier);
    QApplication::sendEvent(ui->textEdit, &EventRelease);
}
 
void Widget::on_button_delete_clicked()
{
    int  key = Qt::Key_Delete; //
 
    QKeyEvent EventPress(QEvent::KeyPress, key, Qt::NoModifier);
    QApplication::sendEvent(ui->textEdit, &EventPress);
 
    QKeyEvent EventRelease(QEvent::KeyRelease, key, Qt::NoModifier);
    QApplication::sendEvent(ui->textEdit, &EventRelease);
}

las relaciones y las relaciones posterior al evento sendEvent como Qt :: QueuedConnection y Qt :: DirectConnection, sólo el primer evento de dos post-distribución es para enviar un mensaje tanto llena el mecanismo posterior al evento y QueuedConnected es la comunicación asíncrona, mientras que los otros dos están sincronizados la comunicación.

img

Rutina 2: Distribución de eventos asíncronos posterior al evento

int count = 0;
 
/*!
 * \brief Widget::Widget 使用postEvent异步分发事件
 * 连续分发10个事件,在事件处理函数中逐个处理
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    int i = 1;
    while(i <= 10)
    {
        //postEvent传递的事件必须是通过new创建的
        qDebug() << "分发第" << i << "个事件";
        QApplication::postEvent(this, new QEvent(NewType));
        i++;
    }
}
 
void Widget::customEvent(QEvent *event)
{
    //使用延时模拟处理过程
    if(event->type() == NewType)
    {
        qDebug() << "现在时间:" <<
                    QTime::currentTime().toString("hh::mm:ss.zzz");
        qDebug() << "第" << ++count << "次收到了事件!处理事件需要一点时间!";
        Delay(1000*2);
    }
 
    QWidget::customEvent(event);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::Delay(unsigned int msec)
{
    QTime start = QTime::currentTime();
 
    QTime end;
    do{
        end = QTime::currentTime();
    } while(start.msecsTo(end) <= msec);
}

Pregunta 6: Mecanismo de filtro de eventos?

Una primera estación de transferencia y un evento de flujo de procesamiento es una EventFilter filtro de eventos (), un objeto A a otro objeto B puede instalar controladores de eventos, o monitor para lograr el evento función de interceptación objeto B. Podemos dar al oyente llamado A, B receptor llamado. Un objeto puede supervisar varios objetos, un objeto también puede supervisar varios sucesos. retornos filtro de eventos verdaderos, dijeron que el evento ha sido procesado, o pasado a la siguiente oyente o el propio receptor.

img

Rutina 3: Filtro de Eventos

/*!
 * \brief Widget::Widget 事件过滤器
 * 不借助Tab键的情况下使用Space键实现控件跳转
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    ui->lineEdit_user->setText(QString("lee"));
    focusNextChild();
    ui->lineEdit_password->setText(QString("*******"));
 
    //监听控件
    ui->lineEdit_user->installEventFilter(this);
    ui->lineEdit_password->installEventFilter(this);
    ui->button_accept->installEventFilter(this);
    ui->button_cancel->installEventFilter(this);
}
 
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    //定义事件处理动作
    if (watched == ui->lineEdit_user || watched == ui->lineEdit_password
        || watched == ui->button_accept || watched == ui->button_cancel)
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *e = static_cast<QKeyEvent *>(event);
            if(e->key() == Qt::Key_Space)
            {
                focusNextChild();
                return true;
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_button_cancel_clicked()
{
    qApp->quit();
}

* Un valor de punto a destacar es responsable de QCoreApplication Si bien la distribución de eventos, sino que es en sí heredado de QObject, por lo que en el caso antes de la distribución, sino también comprobar si otros objetos instalados en sí misma una filtros de eventos, los filtros de sucesos pueden filtrar algunos de los eventos no se libera. *

Rutina 4: QCoreApplication instalar un filtro de eventos

widget.cpp

/*!
 * \brief Filter::eventFilter 用于监听qApp的监听器
 * \return
 */
bool Filter::eventFilter(QObject *obj, QEvent *event)
{
    //阻止所有的鼠标点击事件
    if(event->type() == QEvent::MouseButtonPress)
    {
        qDebug() << "sorry everybody, I gonna filter all the mouse event!";
        return true;
    }
    return QObject::eventFilter(obj,event);
}
 
/*!
 * \brief Widget::Widget
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "mouse press!";
 
    QWidget::mousePressEvent(event);
}

main.c

#include "widget.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    Filter filter;
    a.installEventFilter(&filter);
 
    Widget w;
    w.show();
 
    return a.exec();
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

Puede (), operación de procesamiento personalizado del evento por la re-aplicación de la QCoreApplication notificar.

Rutinario 5: subclase QCoreApplication y anulación notifiquen

newapplication.h

#ifndef NEWAPPLICATION_H
#define NEWAPPLICATION_H
 
#include <QApplication>
 
class NewApplication : public QApplication
{
public:
    NewApplication(int argc, char **argv) : QApplication(argc,argv) {}
 
    virtual bool notify(QObject *, QEvent *);
 
};
 
#endif // NEWAPPLICATION_H
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

newapplication.cpp

#include "newapplication.h"
#include <QMouseEvent>
#include <QDebug>
 
bool NewApplication::notify(QObject *receiver, QEvent *event)
{
    if(event->type() == QMouseEvent::MouseButtonPress)
    {
        qDebug() << "sorry everybody I gonna filter all the mouse press event";
        return true;
    }
 
    return QApplication::notify(receiver,event);
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

widget.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QMouseEvent>
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
protected:
    void mousePressEvent(QMouseEvent *event);
 
private slots:
    void on_pushButton_clicked();
 
private:
    Ui::Widget *ui;
};
 
#endif // WIDGET_H
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "I am mainwindow Widget, I got a mouse event!";
 
    QWidget::mousePressEvent(event);
}
 
void Widget::on_pushButton_clicked()
{
    qDebug() << "I am push button , I got a mouse event!";
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

main.cpp

#include "widget.h"
#include <QApplication>
#include "newapplication.h"
 
int main(int argc, char *argv[])
{
//    QApplication a(argc, argv);
    NewApplication a(argc, argv);
 
    Widget w;
    w.show();
 
    return a.exec();
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

El resultado: Haga clic en cualquier lugar de la interfaz, eventos QAPP se filtran.

img

Resumen: de procesamiento de eventos

1. El re-implementar el controlador de eventos objeto específico, por ejemplo mousePressEvent, keyPressEvent, ShowEvent etc., después de que el evento ha sido procesado a la matriz;

función de evento 2. reimplementar se procesa después del evento para los padres;

3. Instalar un filtro de eventos en el objeto, de modo que otros objetos para controlar el comportamiento de este objeto de evento;

4. QCoreApplication montado en el filtro de evento principal, antes de llamar para notificar distribución evento, determina el manejo de eventos de acuerdo a un filtro (por ejemplo .: descartado);

5. subclase QCoreApplication, reimplementar notificar función de distribución de eventos;

Pregunta 7. cómo utilizar los eventos personalizados?

Escenario: eventos personalizados para una operación en particular es útil definir un período continuo de 10 eventos de clic del ratón NewMouseEvent, 10 veces en una fila, haga clic en la pantalla, activar el procedimiento de calibración de la pantalla.

eventos Personalizados

newmouseevent.h

#ifndef MYEVENT_H
#define MYEVENT_H
 
#include <QEvent>
#include <QString>
 
class NewMouseEvent : public QEvent
{
public:
    explicit NewMouseEvent() :  QEvent(MouseTenClick) {}
    const static Type MouseTenClick = static_cast<Type>(QEvent::User+0x10);
};
 
#endif // MYEVENT_H
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

widget.h

#ifndef MYEVENT_H
#define MYEVENT_H
 
#include <QEvent>
#include <QString>
 
class NewMouseEvent : public QEvent
{
public:
    explicit NewMouseEvent() :  QEvent(MouseTenClick) {}
    const static Type MouseTenClick = static_cast<Type>(QEvent::User+0x10);
};
 
#endif // MYEVENT_H
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "newmouseevent.h"
#include <QMouseEvent>
#include <QTimer>
 
/*!
 * \brief Widget::Widget
 * 创建并分发一种新的事件:鼠标连续点击10次
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    ui->label->installEventFilter(this);
 
    ui->label->setText(tr("请连续点击屏幕以唤醒屏幕校准功能!"));
    ui->label->adjustSize();
 
    m_timer = new QTimer;
    m_timer->setInterval(1000);
    m_timer->start();
    connect(m_timer, SIGNAL(timeout()), SLOT(clearCount()));
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::mousePressEvent(QMouseEvent *event)
{
    QWidget::mousePressEvent(event);
}
 
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() != Qt::LeftButton)
        return;
 
    if(m_timer->isActive())
        m_timer->stop(); //如果计时器在运行,则停止然后重新开始
    m_timer->start();
 
    count++;
 
    if(10 == count)
    {
        count = 0;
 
        NewMouseEvent event;
        qApp->sendEvent(ui->label, &event);
    }
 
    QWidget::mouseReleaseEvent(event);
}
 
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == ui->label && event->type()== NewMouseEvent::MouseTenClick)
    {
        ui->label->setText(tr("你连续点击了10次屏幕,校准程序正在启动!"));
        ui->label->adjustSize();
        return true;
    }
 
    return QWidget::eventFilter(obj,event);
}
 
void Widget::clearCount()
{
    count = 0;
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

Los resultados operativos

Haga clic en el ratón 10 veces consecutivas cuentan una vez un evento personalizado

img

img

Pregunta 8: destinatario del objeto es eliminado a mitad de camino lo que sucede? El oyente se elimina Qué ocurre?

No se pudo enviar? Programa se bloquea?

widget.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QLabel>
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
protected:
 
private slots:
    void slotSendEvent();
    void deleteLabel();
 
private:
    Ui::Widget *ui;
 
    QLabel *m_label;
 
};
 
#endif // WIDGET_H
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QResizeEvent>
#include <QDebug>
 
/*!
 * \brief Widget::Widget
 * 在事件循环分发事件给接收者之前,接收者被删除
 * \param parent
 */
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    //创建小窗口
    m_label = new QLabel(this);
    m_label->setStyleSheet(QString("border:1px solid red;"));
    m_label->setGeometry(QRect(0,0,200,100));
 
    //在qApp发送事件之前销毁小窗口
    QTimer::singleShot(1000, this, SLOT(deleteLabel()));
    //qApp发送事件给小窗口
    QTimer::singleShot(2000, this, SLOT(slotSendEvent()));
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::slotSendEvent()
{
    QResizeEvent re(QSize(300,200), QSize(200,100));
 
    qDebug() << "qApp发送了一个事件给小窗口!";
    qApp->sendEvent(m_label, &re);
}
 
void Widget::deleteLabel()
{
    qDebug() << "小窗口被销毁了!";
    delete m_label;
    m_label = NULL;
}
————————————————
版权声明:本文为CSDN博主「ingy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/simonyucsdy/article/details/82749539

Los resultados operativos

img

Supongo que te gusta

Origin www.cnblogs.com/schips/p/12536411.html
Recomendado
Clasificación