Details
Description
I'm trying to do something like this example, except in Python (from http://doc.qt.io/qt-5/qqmlcomponent.html#engine ):
void MyCppItem::init() { QQmlEngine *engine = qmlEngine(this); // Or: // QQmlEngine *engine = qmlContext(this)->engine(); QQmlComponent component(engine, QUrl::fromLocalFile("MyItem.qml")); QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create()); childItem->setParentItem(this); }
In Python there appears to be no qmlContext or qmlEngine function, but an alternative is available via QQmlEngine.contextForObject. Unfortunately, I can't get this to return anything other than None. According to the docs (http://doc.qt.io/qt-5/qqmlengine.html#contextForObject) the context for any QObject should be "set automatically" by the QQmlEngine, after the object is constructed.
I also ran across this question (https://stackoverflow.com/questions/51946711/access-to-a-qqmlapplicationengine-inside-my-custom-class) from someone writing a C++ program that calls this function, and they appear to be observing similar behavior.
Here's some example code to demonstrate the issue.
QML:
import QtQuick 2.0 import QtQuick.Controls 2.2 Rectangle { width: 200; height: 200 Button { text: "print Hello World" onClicked: MainWindow.Print('hello world') } }
Python:
#!/bin/env python3 # -*- coding: utf-8 -*- from PySide2.QtCore import Slot from PySide2.QtCore import QUrl from PySide2.QtQml import qmlRegisterType from PySide2.QtQml import QQmlEngine from PySide2.QtQuick import QQuickView from PySide2.QtQuick import QQuickItem from PySide2.QtWidgets import QApplication import sys class MainWindow(QQuickView): def __init__(self): super().__init__() self.setSource(QUrl('sample.qml')) self.rootContext().setContextProperty("MainWindow", self) self.show() @Slot('QString') def Print(self, value): print(value) print("context=" + str(QQmlEngine.contextForObject(self))) if __name__ == '__main__': app = QApplication(sys.argv) w = MainWindow() sys.exit(app.exec_())