4

我扩展了QWebEngineView

#ifndef MYQWEBENGINEVIEW_H
#define MYQWEBENGINEVIEW_H
#include <QWebEngineView>
class MyQWebEngineView : public QWebEngineView
{
public:
    MyQWebEngineView(QWidget *parent = 0);
    ~MyQWebEngineView();
protected:
    virtual void paintEvent(QPaintEvent *);
};
#endif // MYQWEBENGINEVIEW_H

但我不能被叫到paintEvent(QPaintEvent *)

#include "myqwebengineview.h"
#include <QPaintEvent>
#include <QPainter>
#include <QWebEngineView>
#include <QWidget>

MyQWebEngineView::MyQWebEngineView(QWidget *parent):QWebEngineView(parent)
{
    qDebug() << "MyQWebEngineView(" << parent << ")";
    qDebug() << "Qt::WA_PaintOnScreen: " << testAttribute(Qt::WA_PaintOnScreen);
    //setAttribute(Qt::WA_PaintOnScreen, true);
}
MyQWebEngineView::~MyQWebEngineView()
{
}
void MyQWebEngineView::paintEvent(QPaintEvent * event)
{
    qDebug() << "paintEvent(" << event << ")";
    QWebEngineView::paintEvent(event);
    //QWidget::paintEvent(event);

    qDebug() << event->rect();
    qDebug() << event->region();
}

谁能告诉我怎么了?

4

2 回答 2

7

不幸的是,小部件QWebEngineView几乎没有捕获任何事件(除了鼠标进入和退出,最近添加的键盘事件),例如参见“[QTBUG-43602] WebEngineView does not handle mouse events”

几乎所有事件(如鼠标移动或绘画)都由QWebEngineView派生RenderWidgetHostViewQtDelegateWidgetQOpenGLWidget.

可以捕获新的子QWebEngineView类型QOpenGLWidget并在该子节点上安装所有需要事件的事件过滤器挂钩。

该解决方案依赖于QWebEngineView. 因此,未来的 Qt 版本可能不支持它。但是,它可用于具有当前 Qt 版本的项目。也许将来会实现一些更方便的捕获QWebEngineView事件的接口。

以下子类QWebEngineView实现:

#ifndef WEBENGINEVIEW_H
#define WEBENGINEVIEW_H

#include <QEvent>
#include <QChildEvent>
#include <QPointer>
#include <QOpenGLWidget>
#include <QWebEngineView>
#include <QPaintEvent>

class WebEngineView : public QWebEngineView
{
    Q_OBJECT

private:
    QPointer<QOpenGLWidget> child_;

protected:
    bool eventFilter(QObject *obj, QEvent *ev)
    {
        // emit delegatePaint on paint event of the last added QOpenGLWidget child
        if (obj == child_ && ev->type() == QEvent::Paint) {
            QPaintEvent *pe = static_cast<QPaintEvent*>(ev);
            // do something with paint event
            // ...
            // or just emit signal to notify other objects
            emit delegatePaint(pe);
        }

        return QWebEngineView::eventFilter(obj, ev);
    }

public:
    WebEngineView(QWidget *parent = nullptr) :
        QWebEngineView(parent), child_(nullptr)
    {
    }

    bool event(QEvent * ev)
    {
        if (ev->type() == QEvent::ChildAdded) {
            QChildEvent *child_ev = static_cast<QChildEvent*>(ev);

            // there is also QObject child that should be ignored here;
            // use only QOpenGLWidget child
            QOpenGLWidget *w = qobject_cast<QOpenGLWidget*>(child_ev->child());
            if (w) {
                child_ = w;
                w->installEventFilter(this);
            }
        }

        return QWebEngineView::event(ev);
    }

signals:
    void delegatePaint(QPaintEvent*);
};

#endif // WEBENGINEVIEW_H

子添加被WebEngineView::event. 子指针被保存并且事件过滤器被安装在这个子节点上。在子绘画事件中,信号WebEngineView::delegatePaint(QPaintEvent*)WebEngineView::eventFilter.

delegatePaint当 Web 视图被某些脚本更改或由于鼠标悬停或任何其他原因而突出显示某些 Web 控件时,始终会发出该信号。

请注意,它与覆盖不同QWebEngineView::paintEvent。以这种方式,只能接收到某些更改的通知。

因此,可以直接在事件中做出反应WebEngineView::eventFilter或连接到信号delegatePaint以通知其他对象有关 Web 视图重绘,例如滚动后查看 QT QWebEngine 渲染?

于 2015-11-06T22:40:33.787 回答
6

我的要求是禁用鼠标点击。按照 Orest 的回答,“w”在 Qt 5.9.3 中始终为 NULL。

QOpenGLWidget *w = qobject_cast<QOpenGLWidget*>(child_ev->child());

所以我修改了Orest的答案。这更适合 Qt 5.9.x。

#ifndef CUSTOMWEBVIEW_H
#define CUSTOMWEBVIEW_H

#include <QWebEngineView>
#include <QOpenGLWidget>
#include <QDebug>
#include <QEvent>

class CustomWebView : public QWebEngineView
{
    Q_OBJECT

public:
    CustomWebView(QWidget* parent = Q_NULLPTR);

protected:
    bool event(QEvent* evt)
    {
        qDebug() << evt->type();

        if (evt->type() == QEvent::ChildPolished)
        {
            QChildEvent *child_ev = static_cast<QChildEvent*>(evt);
            childObj = child_ev->child();

            if (childObj)
            {
                childObj->installEventFilter(this);
            }
        }

        return QWebEngineView::event(evt);
    }

    bool eventFilter(QObject *obj, QEvent *ev)
    {
        if (obj == childObj
                && (ev->type() == QEvent::MouseButtonPress
                    || ev->type() == QEvent::MouseButtonDblClick))
        {
            return true;
        }

        return QWebEngineView::eventFilter(obj, ev);
    }

private:
    QObject *childObj = NULL;
};

#endif // CUSTOMWEBVIEW_H
于 2018-01-09T07:29:04.977 回答