从自定义 QML 库导入 QML 组件

Import QML Components from Custom QML Library

我创建了一个库来存储我为应用程序制作的自定义 QML 组件。我在 python 中使用 Pyside6。这是基本目录的样子:

library
|    |__CustomComponents
|       |__Components1  
|          |__CustomComponent1.qml
|
|__test
   |__MainComponent
      |__main.py
      |__Main.qml

库和测试在同一级别。我希望能够访问 CustomComponent1.qml 文件以在 Main.qml 中使用,但我将如何在 Python 中为该文件编写导入语句?另外,为了能够将 Components1 作为模块导入,我只需要 qmldir 文件吗?如果有一个命令可以用来生成制作模块所需的文件,那就太好了。

编辑:可以同时使用 QQuickView 和 QQmlApplicationEngine 吗?

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()

您必须使用 qmldir 来指示该文件夹中有一个模块,并且要使用它,它必须在引擎的导入列表中,为此您必须使用 addImportPath 方法.

├── 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{

    }
}

QQuickView

在 QQuickView 的情况下,它有一个引擎,所以你必须使用那个引擎,所以变化是:

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{

    }
}