QT eventFilter 事件监测

    Qt 事件模块有一个强大的特性,就是可以设置一个QObject1 的实例可以实时的去监测另一个QObject2的实例的事件,在被监测控件QObject2能看到事件之前,就先被监测的控件QObject看到(拦截)并处理。

    例如这样一个场景,在一个QDialog里有一个QLabel显示一张图片,我们想要双击(double clicked )这个图片QLabel然后就关闭这个QDialog。

    正常情况下,一个QLabel是没有直接的响应双击的信号的,这时候我们就需要监测这个QLabel响应的双击事件了。

    那么该怎样做呢?

    1.首先在QDialog的头文件.h中,声明

    

#ifndef DETAILPIC_H
#define DETAILPIC_H

#include <QDialog>

namespace Ui {
class DetailPic;
}

class DetailPic : public QDialog
{
    Q_OBJECT

public:
    explicit DetailPic(QWidget *parent = 0);
    void loadImage(const QString &filePath);
    ~DetailPic();

protected:
    bool eventFilter(QObject *, QEvent *);


private:
    Ui::DetailPic *ui;
};

#endif // DETAILPIC_H

    这里面主要是protected中的 eventFilter()函数。

bool eventFilter(QObject *obj, QEvent *ev);

    解释一下这个函数,这是被事件过滤器,就是所有被QDialog监测的控件,发生的所有事件都会先执行这个函数。obj为被监测的控件, ev是事件。

2.在QDialog的.cpp文件中 构造函数中首先要给被监测的控件安装事件过滤器。

ui->picLabel->installEventFilter(this);

      这个函数就是安装事件过滤器,ui->picLabel为被监测的控件, 参数this表示谁要监测ui->picLabel的事件。因为我们是想这个QDialog控件来监视picLabel这个控件,所以参数为this.

    3.实现函数bool eventFilter(QObject *obj, QEvent *ev)

bool DetailPic::eventFilter(QObject *obj, QEvent *evn)
{
    if(obj == ui->picLabel)    
    {
        if(evn->type() == QEvent::MouseButtonDblClick)
        {
            this->reject();
            return true;    //事件到此为止,不再需要其他来处理了。
        }
    }

    return QDialog::eventFilter(obj, evn); // 事件继续广播出去,按照普通的方式去处理这个事件。
}

这个函数的参数obj为被监视的控件,ev为发生的事件。

给出所有代码

#include "DetailPic.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include  <QtWidgets>
#include <DetailPic.h>
#include "ui_Detailpic.h"

DetailPic::DetailPic(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DetailPic)
{
    ui->setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_TranslucentBackground);

    ui->picLabel->installEventFilter(this);
}

void DetailPic::loadImage(const QString &filePath)
{
    QUrl url(filePath);
    QNetworkAccessManager manager;
    QEventLoop loop;

    QNetworkReply *reply = manager.get(QNetworkRequest(url));
    //请求结束并下载完成后,退出子事件循环
    connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    //开启子事件循环
    loop.exec();

    QByteArray jpegData = reply->readAll();
    QPixmap pixmap;
    pixmap.loadFromData(jpegData);
    ui->picLabel->setPixmap(pixmap);
    this->resize(pixmap.width(),pixmap.height());

}

DetailPic::~DetailPic()
{
    delete ui;
}

bool DetailPic::eventFilter(QObject *obj, QEvent *evn)
{
    if(obj == ui->picLabel)
    {
        if(evn->type() == QEvent::MouseButtonDblClick)
        {
            this->reject();
            return true;
        }
    }

    return QDialog::eventFilter(obj, evn);;
}

    

猜你喜欢

转载自blog.csdn.net/xiezhongyuan07/article/details/79992099