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はほとんどすべてのイベントをキャッチしません (マウスの開始と終了、最近追加されたキーボード イベントを除く)

ほとんどすべてのイベント (マウスの移動やペイントなど) は、 から派生した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たり、信号に接続して、delegatePaintWeb ビューの再描画について他のオブジェクトに通知することができます。たとえば、QT QWebEngine render after scrolling?を参照してください。

于 2015-11-06T22:40:33.787 に答える