如何使用QtWebEngine获取绘制事件?

如何使用QtWebEngine获取绘制事件?,qt,qtwebengine,Qt,Qtwebengine,我扩展了QWebEngineView \ifndef MYQWEBENGINEVIEW\u H #定义MYQWEBENGINEVIEW_H #包括 MyQWebEngineView类:公共QWebEngineView { 公众: MyQWebEngineView(QWidget*parent=0); ~MyQWebEngineView(); 受保护的: 虚拟虚空paintEvent(QPaintEvent*); }; #endif//MYQWEBENGINEVIEW\u H 但是我无法调用pa

我扩展了
QWebEngineView

\ifndef MYQWEBENGINEVIEW\u H
#定义MYQWEBENGINEVIEW_H
#包括
MyQWebEngineView类:公共QWebEngineView
{
公众:
MyQWebEngineView(QWidget*parent=0);
~MyQWebEngineView();
受保护的:
虚拟虚空paintEvent(QPaintEvent*);
};
#endif//MYQWEBENGINEVIEW\u H
但是我无法调用
paintEvent(QPaintEvent*)

#包括“myqwebengineview.h”
#包括
#包括
#包括
#包括
MyQWebEngineView::MyQWebEngineView(QWidget*父项):QWebEngineView(父项)
{

qDebug()不幸的是,小部件
QWebEngineView
几乎没有捕获任何事件(除了鼠标进入和退出、最近添加的键盘事件),例如,请参见

几乎所有事件(如鼠标移动或绘制)都由
QWebEngineView
私有类型的子委托
RenderWidgetHostViewQtDelegateWidget
处理,该委托派生自
QOpenGLWidget

可以捕获
QOpenGLWidget
类型的
QWebEngineView
的新子级,并在此子级上安装所有所需事件的事件筛选器挂钩

该解决方案依赖于
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
\ifndef WEBENGINEVIEW\u H
#定义WEBENGINEVIEW_H
#包括
#包括
#包括
#包括
#包括
#包括
WebEngineView类:公共QWebEngineView
{
Q_对象
私人:
QPointer-child;
受保护的:
布尔事件过滤器(QObject*obj,QEvent*ev)
{
//上次添加的QOpenGLWidget子级的“在绘制时发出delegatePaint”事件
如果(obj==child_uz&&ev->type()==QEvent::Paint){
QPaintEvent*pe=静态(ev);
//用油漆做点什么
// ...
//或者只是发出信号通知其他对象
发射去极化涂料(pe);
}
返回QWebEngineView::eventFilter(obj,ev);
}
公众:
WebEngineView(QWidget*parent=nullptr):
QWebEngineView(父级)、子级(nullptr)
{
}
bool事件(QEvent*ev)
{
如果(ev->type()==QEvent::ChildAdded){
QChildEvent*child_ev=静态铸造(ev);
//这里还有一个QObject子对象应该被忽略;
//仅使用QOpenGLWidget子级
QOpenGLWidget*w=qobject_cast(child_ev->child());
如果(w){
child_uw=w;
w->installEventFilter(此);
}
}
返回QWebEngineView::事件(ev);
}
信号:
无效授权油漆(QPaint事件*);
};
#endif//WEBENGINEVIEW\u H
子级添加被
WebEngineView::event
捕获。子级指针被保存,事件筛选器安装在此子级上。在子级绘制事件上,信号
WebEngineView::delegatePaint(QPaintEvent*)
WebEngineView::eventFilter
中发出

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

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


因此,可以直接在
WebEngineView::eventFilter
中对事件做出反应,或者连接到信号
delegatePaint
以通知其他对象有关Web视图重新绘制的信息,例如,请参见我的要求是禁用鼠标单击。 按照Orest的回答,Qt5.9.3中的“w”总是空的

QOpenGLWidget *w = qobject_cast<QOpenGLWidget*>(child_ev->child());
QOpenGLWidget*w=qobject\u cast(child\u ev->child());
所以我修改了答案,按照Orest,这更适合Qt5.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
\ifndef CUSTOMWEBVIEW\u H
#定义CUSTOMWEBVIEW\u H
#包括
#包括
#包括
#包括
类CustomWebView:公共QWebEngineView
{
Q_对象
公众:
CustomWebView(QWidget*parent=Q_NULLPTR);
受保护的:
布尔事件(QEvent*evt)
{
qDebug()类型();
if(evt->type()==QEvent::ChildPolished)
{
QChildEvent*child_ev=静态(evt);
childObj=child_ev->child();
if(childObj)
{
childObj->installEventFilter(此);
}
}
返回QWebEngineView::event(evt);
}
布尔事件过滤器(QObject*obj,QEvent*ev)
{
if(obj==childObj
&&(ev->type()==QEvent::MouseButtonPress
||ev->type()==QEvent::MouseButtonDblClick)
{
返回true;
}
返回QWebEngineView::eventFilter(obj,ev);
}
私人:
QObject*childObj=NULL;
};
#endif//CUSTOMWEBVIEW\u H

我会深入研究源代码——我不希望QWebEngine通过正常的
paintEvent
机制来绘制自己,因为它的渲染是基于QtQuick 2(以及OpenGL)的…
QWebEngineView
不会重新实现
paint
。除了使用OpenGl覆盖外,所有光栅集成都可能直接在
事件中完成。
尝试挂接,看看是否有绘制事件发生。@KubaOber你能解释一下
挂接该部分吗?@JinKwon By hooKing是为了在WIGET上安装一个事件过滤器。然后你会看到你是否捕获了任何代码> QEng::Prime< /Cord> @ KubaOber。我不熟悉QT和C++。你想让我试试吗?谢谢。这在5.9不再有用了。有什么想法做类似于5.9的事情吗?我能使它“工作”。通过检查
child\u ev->child()->metaObject()->className()
i