[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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.