You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML中JavaScript模块导入不遵循qmldir的prefer设置求助

解决QML模块中JS资源导入不遵循qmldir prefer配置的热重载问题

问题分析

当前实现QML热重载时,已通过本地路径加载主QML文件、在qmldir中配置prefer ./path/to/module实现了多数资源的热更新,但存在特殊场景:QML模块的JavaScript文件中导入其他QML模块时,不会遵循qmldir的prefer设置。具体表现为:修改模块B的test函数输出后,主QML直接调用B.test能看到更新,但模块A的JS文件中调用B.test仍显示旧内容。

解决方案

针对CMake构建的Qt应用,可通过以下步骤修复:

1. 强制JS资源使用文件系统路径加载

在CMake配置中,确保QML模块的JS资源不被打包到Qt资源系统,保留在本地文件系统。修改CMakeLists.txt,禁用资源打包并对齐模块输出路径与源码路径:

# 模块A配置示例
qt_add_qml_module(A
    URI A
    VERSION 1.0
    QML_FILES
        qml/A.qml
    JS_FILES
        js/A.js
    # 禁用资源打包,强制文件系统加载
    NO_RESOURCE_TARGET_PATH
)

# 设置模块输出路径与源码路径一致,确保prefer路径生效
set_target_properties(A PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/modules/A"
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/modules/A"
)

# 模块B执行相同配置
qt_add_qml_module(B
    URI B
    VERSION 1.0
    QML_FILES
        qml/B.qml
    JS_FILES
        js/B.js
    NO_RESOURCE_TARGET_PATH
)

set_target_properties(B PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/modules/B"
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/modules/B"
)

2. 调整JS文件的导入方式

在模块A的JS文件中,改用相对文件路径直接导入模块B的资源,避免依赖模块URI的缓存:

// A.js中修改导入方式,从相对路径加载B的JS
.import "./../B/js/B.js" as B

若B是含QML类型的模块,可在JS中明确指定文件系统路径导入:

.import "file:///${Qt.resolvedUrl('.')}/../B" as B

3. 禁用QML引擎缓存

在应用初始化代码中,设置环境变量强制禁用QML缓存,确保每次启动都重新加载资源:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDir>

int main(int argc, char *argv[])
{
    // 禁用QML磁盘与网络缓存
    qputenv("QML_DISABLE_DISK_CACHE", "1");
    qputenv("QML_DISABLE_NETWORK_CACHE", "1");

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    // 加载本地主QML文件
    const QUrl url(QStringLiteral("file:///%1/main.qml").arg(QDir::currentPath()));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

4. 校验qmldir配置

确保每个模块的qmldir中prefer路径是相对主QML文件的路径,而非模块内部相对路径:

// 模块A的qmldir示例
module A
prefer ./modules/A
plugin Aplugin

验证步骤

  1. 修改模块B的test函数输出内容
  2. 直接重启应用(无需重建项目)
  3. 检查主QML和模块A的JS中调用B.test的输出是否均已更新

内容的提问来源于stack exchange,提问作者skaldesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:08:14