CefView / QCefView

A Qt Widget encapsulated CEF view based on QWidget
https://cefview.github.io/QCefView/
GNU Lesser General Public License v2.1
521 stars 137 forks source link

[FEATURE] Using QCefView from QML #313

Open agostonsipos opened 12 months ago

agostonsipos commented 12 months ago

I would like to use this component from a QtQuick application. I found https://github.com/CefView/QCefView/issues/34 which is closed but I did not manage to succeed.

When running the app, all I get is a grey screen. In the verbose logs, it can be seen that network communication is actually happening.

I am using MacOS 13 (Ventura), clang 13 compiler and Qt 5.15

My code can be found in a comment below. Mostly I was trying the method https://github.com/edelhirsch/widgetitem is recommending. The same code works for the QPushButton widget used in that repo.

agostonsipos commented 12 months ago

main.cpp

#include <QQmlApplicationEngine>
#include <QApplication>

#include "Browser.h"

static const QString url = "https://google.com/";

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QCefConfig config;
    config.setUserAgent("QCefViewTest");
    config.setLogLevel(QCefConfig::LOGSEVERITY_VERBOSE);
    config.setBridgeObjectName("CallBridge");
    config.setRemoteDebuggingPort(9000);
    config.setBackgroundColor(Qt::lightGray);

    config.setWindowlessRenderingEnabled(true);

    config.addCommandLineSwitch("use-mock-keychain");
    config.addCommandLineSwitch("in-process-gpu");
    config.addCommandLineSwitchWithValue("renderer-process-limit", "1");

    QCefContext context(&app, argc, argv, &config);

    qmlRegisterType<Browser>("Web", 1, 0, "Browser");

    QCefSetting setting;
    setting.setBackgroundColor(QColor::fromRgb(0, 0, 255));

    QCefView view(url, &setting, nullptr);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url, &view](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
        auto browser = obj->findChild<Browser*>();
        browser->setView(&view);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15

import Web 1.0

Window {
    width: 1080
    height: 800
    visible: true
    title: qsTr("Hello World")

    Browser {
        anchors.fill: parent
    }
}

Browser.h

#pragma once

#include <QQuickPaintedItem>

#include "QCefContext.h"
#include "QCefView.h"

class Browser : public QQuickPaintedItem {
    Q_OBJECT
    QML_ELEMENT

public:
    Browser(QQuickItem* parent = nullptr);
    ~Browser();

    void setView(QWidget* view);

    void paint(QPainter *painter) override;

    void mousePressEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;

protected:
    QWidget* m_view;
};

Browser.cpp

#include "Browser.h"

#include <QPainter>
Browser::Browser(QQuickItem *parent) : QQuickPaintedItem(parent) {
    setFillColor(QColor::fromRgb(255, 0, 0));

    setAcceptTouchEvents(true);
    setAcceptedMouseButtons(Qt::AllButtons);
}

Browser::~Browser() {}

void Browser::setView(QWidget* view) {
    m_view = view;
}

void Browser::paint(QPainter *painter) {
    if (m_view) {
        auto dev = painter->device();
        m_view->resize(dev->width(), dev->height());
        m_view->update();
        m_view->render(painter);
    }
}

void Browser::mousePressEvent(QMouseEvent *event)
{
    if(m_view) {
        QCoreApplication::sendEvent(m_view, event);
        update();    m_view->update();
    }
}

void Browser::mouseReleaseEvent(QMouseEvent *event)
{
    if(m_view) {
        QCoreApplication::sendEvent(m_view, event);
        update();    m_view->update();
    }
}
agostonsipos commented 12 months ago

Some logs:

[0906/134850.269502:VERBOSE1:widevine_cdm_component_installer.cc(122)] Register Widevine CDM with Chrome
[0906/134850.280649:VERBOSE1:network_delegate.cc(35)] NetworkDelegate::NotifyBeforeURLRequest: https://update.googleapis.com/service/update2/json
[0906/134850.283576:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.312840:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.317920:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.318297:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.328553:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.328536:VERBOSE1:request_sender.cc(180)] Request completed from url: https://update.googleapis.com/service/update2/json
[0906/134850.329294:VERBOSE1:tls_handshaker.cc(100)] TlsClient: Continuing handshake
[0906/134850.331796:VERBOSE1:tls_client_handshaker.cc(508)] Client: handshake finished
[0906/134850.336167:VERBOSE1:component_updater_service.cc(449)] Update completed with error 0
tishion commented 12 months ago

try this:

replace this line: m_view->resize(dev->width(), dev->height());

with: m_view->resize(size());

tishion commented 12 months ago

And, it is absolutely feasible to port QCefView to QML, but I really have no time for this. Sorry..

agostonsipos commented 11 months ago

Thank you for your answer and the suggestion. Unfortunately, it does not fix the issue.

If I found out that there is a simple fix, I'd be happy to pr it. Sadly, I have no idea.