14

を使用してロードしたいファイルがmain.qmlあります。 ファイルの内容は動的であり、別のプログラムがその内容を変更して上書きする可能性があります。そこで、ファイルの変更を検出して Signal を起動するための C++ コードを書きました。 私の問題は、ローダーにファイルを強制的にリロードさせる方法がわからないことです。dynamic.qmldynamic.qmlmain.qmlLoader {}
dynamic.qml

これは私の現在の仕事です:

MainController {
    id: mainController
    onInstallationHelpChanged: {
        helpLoader.source = "";
        helpLoader.source = "../dynamic.qml";
    }
}

Loader {
    id: helpLoader

    anchors.fill: parent
    anchors.margins: 60
    source: "../dynamic.qml"
}



QML Engine はファイルをキャッシュしていると思いdynamic.qmlます。そのため、ローダーをリロードするたびに、古いコンテンツが表示されます。なにか提案を?

4

2 に答える 2

12

Loadersプロパティを空の文字列に設定したtrimComponentCache()、QQmlEngineを呼び出す必要があります。言い換えると:source

helpLoader.source = "";
// call trimComponentCache() here!!!
helpLoader.source = "../dynamic.qml";

これを行うには、QQmlEngine への参照を持つ C++ オブジェクトを QML に公開する必要があります (Qt と StackOverflow の多くの例がそれを支援します)。

trimComponentCache は QML に、現在使用していないすべてのコンポーネントを忘れるように指示し、必要なことだけを行います。

更新 -もう少し詳しく説明します。

たとえば、QQmlEngine へのポインターを受け取り、trimComponentCache メソッドを公開するクラスをどこかで定義します。

class ComponentCacheManager : public QObject {
    Q_OBJECT
public:
    ComponentCacheManager(QQmlEngine *engine) : engine(engine) { }

    Q_INVOKABLE void trim() { engine->trimComponentCache(); }

private:
    QQmlEngine *engine;
};

次に、QQuickView を作成するときに、上記のいずれかをコンテキスト プロパティとしてバインドします。

QQuickView *view = new QQuickView(...);
...
view->rootContext()->setContextProperty(QStringLiteral("componentCache", new ComponentCacheManager(view->engine());

次に、QML で次のようなことができます。

helpLoader.source = "";
componentCache.trim();
helpLoader.source = "../dynamic.qml";
于 2013-10-26T08:58:59.150 に答える
4

私は純粋な QML ソリューションを望んでいました。loader.sourceこれは URL ( ) であることに気付き、 HTML を使用してリクエストでfile:///HTTP キャッシュを使用する方法を思い出しました。の最後に?t=Date.now()追加してみましたが、確かに機能します。?t=1234loader.source

import QtQuick 2.0

Item {
    Loader {
        id: loader
        anchors.fill: parent
        property string filename: "User.qml"
        source: filename

        function reload() {
            source = filename + "?t=" + Date.now()
        }
    }

    Timer {
        id: reloadTimer
        interval: 2000
        repeat: true
        running: true
        onTriggered: {
            loader.reload();
        }
    }
}

XMLHttpRequest を使用してリロードをトリガーする前に、ファイルの内容の変更をチェックする別の例も書きました。

import QtQuick 2.0

Item {
    Loader {
        id: loader
        anchors.fill: parent
        property string filename: "AppletUser.qml"
        property string fileContents: ""
        source: ""

        function reload() {
            source = filename + "?t=" + Date.now()
        }

        function checkForChange() {
            var req = new XMLHttpRequest();
            req.onreadystatechange = function() {
                if (req.readyState === 4) {
                    if (loader.fileContents != req.responseText) {
                        loader.fileContents = req.responseText;
                        loader.reload();
                    }
                }
            }
            req.open("GET", loader.filename, true);
            req.send();
        }

        onLoaded: {
            console.log(source)
        }

        Timer {
            id: reloadTimer
            interval: 2000
            repeat: true
            running: true
            onTriggered: loader.checkForChange()
        }

        Component.onCompleted: {
            loader.checkForChange()
        }
    }

}
于 2016-08-10T21:22:44.490 に答える