laurapons
laurapons

Reputation: 1093

Is there any way to embed a QWidget inside a QQmlApplicationEngine or QQuickView?

I found a way to embed a QWidget in a QML, by using QQuickWidget render (anchoring, the QWidget with the QQuickWidget position), but I am trying to do the same using QQuickView/QmlApplicationEngine, which uses a different rendering system, and the QWidget is not shown.

Any ideas? Thanks in advance!

Upvotes: 1

Views: 2355

Answers (1)

laurapons
laurapons

Reputation: 1093

None of the posts linked on the comments answered my question. There is this small work around (for those who need it):

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

    QQmlApplicationEngine *engine = new QQmlApplicationEngine(&app);
    engine->load(QUrl("qrc:/qml/main.qml"));
    QQuickWindow* qmlwindow = qobject_cast<QQuickWindow *>(engine->rootObjects().first());

    CustomWidget *customwidget = new CustomWidget();
    QWindow* customwidgetwindow = QWindow::fromWinId(customwidget->winId());

    customwidgetwindow->setParent(qmlwindow);
    customwidget->show();

    if (window) {
        QQuickItem *qmlCustomWidget = qmlwindow->findChild<QQuickItem*>("qmlcustomwidget");
        if (qmlCustomWidget) {
            new WidgetAnchor(customwidgetwindow, qmlCustomWidget);
        }
    }

return app.exec();
}

Where CustomWidget is QWidget based class, and WidgetAnchor.cpp is:

WidgetAnchor::WidgetAnchor(QWidget* pWidget, QQuickItem* pItem)
    : QObject(pWidget),
      _pWidget(pWidget),
      _pQuickItem(pItem)
{
    connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry);
    connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry);
    connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry);
    connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry);
    updateGeometry();
}

void WidgetAnchor::updateGeometry() {
    if (_pQuickItem) {
        QRectF r = _pQuickItem->mapRectToItem(nullptr, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height()));
    _pWidget->setGeometry(r.toRect());
    }
}

And on main.qml you have:

import QtQuick 2.0
import QtQuick.Window 2.3

Window {
    id: root
    visible: true
    width: 500; height: 500

    Item {
        objectName: "qmlcustomwidget"
        anchors.fill: parent
    }
}

Upvotes: 0

Related Questions