Reputation: 145
I have created a library to store custom QML components that I am making for an application. I am using Pyside6 with python. This is what the basic directory looks like:
library
| |__CustomComponents
| |__Components1
| |__CustomComponent1.qml
|
|__test
|__MainComponent
|__main.py
|__Main.qml
library and test are on the same level. I want to be able to access the CustomComponent1.qml file for use in the Main.qml, but how would I go about writing an import statement for that in Python? Also, to be able to import Components1 as a module, is the qmldir file all I need to have there? It would be neat if there is a command I can use to generate the files I need to make a module.
Edit: Possible to use QQuickView and QQmlApplicationEngine together?
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView);
newWidget = newWidget()
view.rootContext().setContextProperty("headerWidget", headerWidget)
qml_file = os.fspath(Path(__file__).resolve().parent / 'Main.qml')
view.setSource(QUrl.fromLocalFile(qml_file))
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
Upvotes: 1
Views: 2835
Reputation: 243955
You have to use qmldir to indicate that there is a module in that folder and for it to be used it must be in the list of imports of the engine and for this you must use the addImportPath
method.
├── library
│ └── CustomComponents
│ └── Components1
│ ├── CustomComponent1.qml
│ └── qmldir
└── test
└── MainComponent
├── main.py
└── main.qml
CustomComponent1.qml
import QtQuick
Rectangle{
id: root
width: 100
height: 100
color: "salmon"
}
qmldir
module Components1
CustomComponent1 CustomComponent1.qml
main.py
import os
from pathlib import Path
import sys
from PySide6.QtCore import QCoreApplication, Qt, QUrl
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
LIBRARY_DIR = CURRENT_DIRECTORY.parents[1] / "library" / "CustomComponents"
def main():
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.addImportPath(os.fspath(LIBRARY_DIR))
url = QUrl.fromLocalFile(os.fspath(CURRENT_DIRECTORY / "main.qml"))
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(
handle_object_created, Qt.ConnectionType.QueuedConnection
)
engine.load(url)
sys.exit(app.exec())
if __name__ == "__main__":
main()
main.qml
import QtQuick
import QtQuick.Window
import Components1
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
CustomComponent1{
}
}
In the case of QQuickView, it has an engine so you must use that one, so the changes are:
main.py
import os
from pathlib import Path
import sys
from PySide6.QtCore import QCoreApplication, Qt, QUrl
from PySide6.QtGui import QGuiApplication
from PySide6.QtQuick import QQuickView
CURRENT_DIRECTORY = Path(__file__).resolve().parent
LIBRARY_DIR = CURRENT_DIRECTORY.parents[1] / "library" / "CustomComponents"
def main():
app = QGuiApplication(sys.argv)
view = QQuickView()
view.engine().addImportPath(os.fspath(LIBRARY_DIR))
url = QUrl.fromLocalFile(os.fspath(CURRENT_DIRECTORY / "main.qml"))
def handle_status_changed(status):
if status == QQuickView.Error:
QCoreApplication.exit(-1)
view.statusChanged.connect(
handle_status_changed, Qt.ConnectionType.QueuedConnection
)
view.setSource(url)
view.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
main.qml
import QtQuick
import Components1
Rectangle {
width: 640
height: 480
CustomComponent1{
}
}
Upvotes: 4