Qt之事件系统_实践篇

简述:

本篇主要叙述Qt中的事件系统,在实际开发工程中所用到的经验。

如果对Qt事件理论知识不懂,访问https://blog.csdn.net/QQ1402369668/article/details/104224896

最简单/直接的事件处理

mousePressEvent()

void Widget::mousePressEvent(QMouseEvent *e)
{
    if(Qt::LeftButton == e->button()){
        qDebug()<<"mousePressEvent() Left";
    }
    else if (Qt::RightButton == e->button()) {
        qDebug()<<"mousePressEvent() Right";
    }
    else {

    }
}

paintEvent()

void Widget::paintEvent(QPaintEvent *event)
{
    //背景半透明
    QPainter p;
    p.begin(this);
    p.fillRect(rect(), QColor(0,0,0,127));
    p.end();
}

在这里插入图片描述

事件过滤器

注意:以下这种情况

情形1:

ui->pushButton->installEventFilter(this);

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

    return QObject::eventFilter(obj, event); //其他的默认调用父类的方法
}

void Widget::on_pushButton_clicked()
{
    qDebug()<<"on_pushButton_clicked()";
}

在这里插入图片描述

情形2:

ui->pushButton->installEventFilter(this);

bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == ui->pushButton){
        if(event->type() == QEvent::MouseButtonPress){
            qDebug()<<"eventFilter() ui->pushButton MouseButtonPress";
            return true; //修改了此处
        }
    }

    return QObject::eventFilter(obj, event); //其他的默认调用父类的方法
}

void Widget::on_pushButton_clicked()
{
    qDebug()<<"on_pushButton_clicked()";
}

在这里插入图片描述

这两种情况比较:

事件先经过事件过滤器,再经过槽函数;

事件过滤器返回false, 会继续传播到槽函数;

事件过滤器返回true,不会继续,槽函数不会执行;

自定义事件:

为什么要自定义事件

1.信号槽是一对一的,当要在多个地方响应同一个信号的时候,使用信号槽会显得臃肿。

实现

首先自定义事件类

CustomEvent.h

#ifndef CUSTOMEVENT_H
#define CUSTOMEVENT_H

#include <QObject>
#include <QEvent>
#include <QVariant>

//事件类型
enum ECustomEventType{
    ETest1 = QEvent::User + 1,
    ETest2,
};

class CustomEvent : public QEvent
{
public:

    /**
    * 概述:
    * 参数:QEvent的类型,自定义参数...
    * 返回值:
    */
    explicit CustomEvent(ECustomEventType type,
                         QVariant par1 = QVariant(),
                         QVariant par2 = QVariant(),
                         QVariant par3 = QVariant(),
                         QVariant par4 = QVariant(),
                         QVariant par5 = QVariant(),
                         QVariant par6 = QVariant(),
                         QVariant par7 = QVariant()
            );

private:
    QVariant m_par1;
    QVariant m_par2;
    QVariant m_par3;
    QVariant m_par4;
    QVariant m_par5;
    QVariant m_par6;
    QVariant m_par7;

friend class Widget;

};

#endif // CUSTOMEVENT_H

CustomEvent.cpp

#include "customevent.h"

CustomEvent::CustomEvent(ECustomEventType type,
                         QVariant par1,
                         QVariant par2,
                         QVariant par3,
                         QVariant par4,
                         QVariant par5,
                         QVariant par6,
                         QVariant par7
        )
    : QEvent(Type(type) ),
      m_par1(par1),
      m_par2(par2),
      m_par3(par3),
      m_par4(par4),
      m_par5(par5),
      m_par6(par6),
      m_par7(par7)
{

}

Widget.cpp

//自定义事件
//发送事件
void Widget::postEventToObj(ECustomEventType eType,
                            QVariant par1, QVariant par2)
{
    CustomEvent* pEvent = new CustomEvent(eType,
                      par1, par2
                );
    QCoreApplication::postEvent(this, pEvent); //注意:post方式event必须在堆上分配
}
//接收事件
bool Widget::event(QEvent *ev)
{
    switch (ECustomEventType(ev->type()) ) {

    case ETest1: //ETest1
    {
        CustomEvent *pCustomEvent = dynamic_cast<CustomEvent*>(ev);
        qDebug()<<"ETest1"<< pCustomEvent->m_par1<<pCustomEvent->m_par2;

        return true;
    }
    break;

    case ETest2: //ETest2
    {
        CustomEvent *pCustomEvent = dynamic_cast<CustomEvent*>(ev);
        qDebug()<< "ETest2"<<pCustomEvent->m_par1<<pCustomEvent->m_par1;

        return true;
    }
    break;

    default:
        break;

    }

    return QWidget::event(ev); //调用默认父类函数
}

调用:

postEventToObj(ETest1, 111,222);
postEventToObj(ETest2, 333,444);

在这里插入图片描述

在这里插入图片描述

事件循环

事件循环QEventLoop 网络http请求

//http get请求
void Widget::httpGet()
{
    // URL
    QString baseUrl = "http://www.csdn.net/";

    // 构造请求
    QNetworkRequest request;
    request.setUrl(QUrl(baseUrl));

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    // 发送请求
    QNetworkReply *pReplay = manager->get(request);

    // 开启一个局部的事件循环,等待响应结束,退出
    QEventLoop eventLoop;
    QObject::connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

    // 获取响应信息
    QByteArray bytes = pReplay->readAll();
    qDebug() << bytes;
}

因为请求的过程是异步的,所以此时使用 QEventLoop 开启一个局部的事件循环,等待响应结束,事件循环退出。

**注意:**开启事件循环的同时,程序界面将不会响应用户操作(界面被阻塞)。

QApplication::processEvents()处理密集操作界面响应

在使用Qt的过程中,经常会碰到需要运行耗时的逻辑代码的时候,一般都采用多线程进行处理,这样可以保证主线程(界面)不会被占用,导致用户操作无效,出现等待无响应现象。
Qt本身提供一个函数QApplication::processEvents()来处理。

//processEvents()处理密集操作界面响应
void Widget::on_pushButton_4_clicked()
{
    QDateTime time = QDateTime::currentDateTime();
    time = time.addSecs(20);
    while(1)
    {
//        QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,20);

        if(QDateTime::currentDateTime() > time)
            return;
    }
}

运行后,我们一直点界面,就会出现如下情形,界面卡死状态;

在这里插入图片描述

如何解决哪?

​ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,20);

放开即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值