如何使用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