我延长了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();
}
有人可以告诉我出了什么问题吗?
答案 0 :(得分:7)
不幸的是,小部件QWebEngineView
几乎不会捕获任何事件(鼠标进入和退出,最近添加的键盘事件除外),例如,请参阅"[QTBUG-43602] WebEngineView does not handle mouse events"。
几乎所有事件(如鼠标移动或绘制)都由QWebEngineView
私有类型RenderWidgetHostViewQtDelegateWidget
的子代理处理,该代理来自QOpenGLWidget
。
可以捕获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
中发出。
当某些脚本更改Web视图或由于鼠标悬停或任何其他原因突出显示某些Web控件时,始终会发出信号delegatePaint
。
请注意,它与覆盖QWebEngineView::paintEvent
不同。通过这种方式,只能接收有关更改内容的通知。
因此,可以直接在WebEngineView::eventFilter
中对事件做出反应,或者连接到信号delegatePaint
以通知其他对象有关Web视图重新绘制的信息,例如,请参阅QT QWebEngine render after scrolling?
答案 1 :(得分:5)
我的要求是禁用鼠标点击。 按照Orest的回答,&#34; w&#34;在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