Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] How to create WebView in QML from C++ code?



  • Hi guys!

    I have a question with QtWebKit. I want to create a WebView element in side my QML file using C++ plugin. As I known fro now in Qt 5.0.0 exist QGraphicsWebView class. But When I try use it to add in QML contents I have crash on call methods load(QUrl()). The code look like this:

    @#include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include <QtWebKit/QtWebKit>
    #include <QtWebKitWidgets/QtWebKitWidgets>
    #include <QDebug>

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

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/AppsnackSDKTest/main.qml"&#41;&#41;;
    viewer.showExpanded();
    
    QQuickItem* wnd = (QQuickItem*)qApp->allWindows().last();
    QGraphicsWebView* view = new QGraphicsWebView();
    view->setProperty("width", QVariant(300));
    view->setProperty("height", QVariant(200));
    view->setProperty("id", QVariant("webViewTemp"));
    view->setProperty("objectName", QVariant("webViewTemp"));
    view->setProperty("color", QVariant(QColor("red")));
    //wnd->parentItem()->childItems().last()->childItems().append((QQuickItem*)view); <-- Try to add a element to QML elements tree
    QQuickItem* rootItem = wnd->parentItem()->childItems().last();
    QQuickView* rootComponent = (QQuickView*)rootItem;
    if(rootComponent != NULL)
    {
        rootComponent->rootContext()->setContextProperty("webViewTmp", view); //<-- crash here.
    }
    else
    {
        qDebug()<<"ERROR: object not created: "<<rootComponent;
    }
    
    return app.exec&#40;&#41;;
    

    }
    @

    What I do wrong? Thanks for any help!

    Also I try this code:
    @#include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include <QtWebKit/QtWebKit>
    #include <QtWebKitWidgets/QtWebKitWidgets>
    #include <QDebug>

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

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/AppsnackSDKTest/main.qml"&#41;&#41;;
    viewer.showExpanded();
    
    //QQuickItem* wnd = (QQuickItem*)qApp->allWindows().last();
    QGraphicsWebView* view = new QGraphicsWebView();
    view->setProperty("width", QVariant(300));
    view->setProperty("height", QVariant(200));
    view->setProperty("id", QVariant("webViewTemp"));
    view->setProperty("objectName", QVariant("webViewTemp"));
    view->setProperty("color", QVariant(QColor("red")));
    view->load(QUrl("http://appsnack.com"));
    viewer.rootContext()->setContextProperty("webViewTmp", view);
    
    return app.exec&#40;&#41;;
    

    }
    @


  • Moderators

    QGraphicsWebView is QtWidget-based. You cannot use QWidget children in QML2 QWindows.

    Also, in order for a componen created in c++ be visible in QML, you need to properly reparent it.



  • [quote author="sierdzio" date="1356529337"]QGraphicsWebView is QtWidget-based. You cannot use QWidget children in QML2 QWindows.

    Also, in order for a componen created in c++ be visible in QML, you need to properly reparent it.[/quote]

    Thanks for the quickly reply. How I can create QML WebView in C++ code? Or it's impossible for now? Where I can find some examples for it? In documentation I can't find any information about it. Thanks!


  • Moderators

    I have only tried it with custom files, not built-in ones, but here you go:
    @
    myComp = new QQmlComponent(engine, parent);
    myComp->setData("import Whatever 1.0"
    "WebView { height: 500; width: 500 //etc. }");
    if (myComp->isReady()) {
    QObject *obj = myComp->create();
    obj->setProperty("parent", QVariant::fromValue(parent));
    }
    @

    Brain-to-terminal, not tested. In my code, I don't use ::setData(), so I'm not sure it would work.



  • [quote author="sierdzio" date="1356531410"]I have only tried it with custom files, not built-in ones, but here you go:
    @
    myComp = new QQmlComponent(engine, parent);
    myComp->setData("import Whatever 1.0"
    "WebView { height: 500; width: 500 //etc. }");
    if (myComp->isReady()) {
    QObject *obj = myComp->create();
    obj->setProperty("parent", QVariant::fromValue(parent));
    }
    @

    Brain-to-terminal, not tested. In my code, I don't use ::setData(), so I'm not sure it would work.[/quote]

    Thanks for the code! I have try it and found the small problem. I was modify it to this version:
    @
    QQuickView* wnd = (QQuickView*)qApp->allWindows().last();
    QQuickItem* wndContentItem = wnd->contentItem();
    rootItem = wndContentItem->childItems().last();
    QQmlEngine* engine = wnd->engine();

    myComp = new QQmlComponent(engine, rootItem);
    QString component("import QtQuick 2.0 \n import QtWebKit 3.0 \n WebView {anchors.top: parent.top; height: 300; width: 200; url:\"http://google.com\" }");
    connect(myComp, SIGNAL(statusChanged(QQmlComponent::Status)), SLOT(sss(QQmlComponent::Status)));
    myComp->setData(component.toUtf8(), QStringLiteral("qml/AppsnackSDKTest/main.qml"));
    

    @

    Because I need get 'engine' and 'parent' objects. So, I try get it from qApp window. And I have received the error like this:
    @
    QML debugging is enabled. Only use this in a safe environment.
    ASSERT: "!isEmpty()" in file ../../../../Applications/Qt5.0.0/5.0.0/clang_64/include/QtCore/qlist.h, line 290
    The program has unexpectedly finished.
    @

    Can you check my code and tell me what I do wrong? Thanks!

    I known the problem in this few line of code:
    @
    QQuickView* wnd = (QQuickView*)qApp->allWindows().last(); //Try gett a main window of app
    QQuickItem* wndContentItem = wnd->contentItem(); //Try QML content
    rootItem = wndContentItem->childItems().last(); //Try get a last parent object (it's always one, so it's must be parent, but it's NULL !!!!!)
    @

    Thanks for the help!


  • Moderators

    @
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/AppsnackSDKTest/main.qml"));
    viewer.showExpanded();

    // ...

    myComp = new QQmlComponent(viewer.engine(), viewer.rootObject());
    @



  • [quote author="sierdzio" date="1356538127"]@
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/AppsnackSDKTest/main.qml"));
    viewer.showExpanded();

    // ...

    myComp = new QQmlComponent(viewer.engine(), viewer.rootObject());
    @[/quote]

    Thank for the help! It's works! I create a new component before app loading QML file. :-) Now all works fine! Thanks!


  • Moderators

    Pleasure :-)

    I was afraid my last post could be a bit too enigmatic, but had no time to write more. Anyway, it works for you, so we're all happy.


Log in to reply