I extended 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
But I can't get paintEvent(QPaintEvent *)
called.
#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();
}
Can anybody please tell me what's wrong?
Unfortunately the widget QWebEngineView
does not catch almost any events (except mouse enter and exit, recently added keyboard events), for example see "[QTBUG-43602] WebEngineView does not handle mouse events".
Almost all events (like mouse move or paint) are handled by QWebEngineView
child delegate of private type RenderWidgetHostViewQtDelegateWidget
that is derived from QOpenGLWidget
.
It is possible to catch new child of QWebEngineView
of type QOpenGLWidget
and to install on this child the event filter hook for all needed events.
That solution relies on undocumented structure of QWebEngineView
. Thus it may be not supported by future Qt releases. However, it is usable for projects with current Qt versions. Maybe in the future some more convenient interface to catch QWebEngineView
events will be implemented.
The following subclass of QWebEngineView
implements that:
#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
Child adding is caught by WebEngineView::event
. The child pointer is saved and the event filter is installed on this child. On the child paint event the signal WebEngineView::delegatePaint(QPaintEvent*)
is emitted in WebEngineView::eventFilter
.
The signal delegatePaint
is always emitted when the Web view is changed by some script or by highlighting of some web controls due to mouse hover or for any other reason.
Note that it is not the same as overriding QWebEngineView::paintEvent
. In that way it is possible only to receive notification that something is changed.
So, it is possible to react on the event directly in WebEngineView::eventFilter
or to connect to the signal delegatePaint
to notify other objects about Web view repainting, for example see QT QWebEngine render after scrolling?
My demand is disabling the mouse click. Follow Orest's answer, the "w" always is NULL in the Qt 5.9.3.
QOpenGLWidget *w = qobject_cast<QOpenGLWidget*>(child_ev->child());
So I modify the answer follow Orest. That is more suitable for 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With