我有main.qml和dynamic.qml文件,我想使用Loader {}在main.qml上加载dynamic.qml。
dynamic.qml文件的内容是动态的,另一个程序可能会更改其内容并覆盖它。因此,我编写了一些C++代码,用于检测文件中的更改并触发信号。
我的问题是,我不知道如何才能强迫装载机重新加载文件。
这是我目前的工作:
MainController {
id: mainController
onInstallationHelpChanged: {
helpLoader.source = "";
helpLoader.source = "../dynamic.qml";
}
}
Loader {
id: helpLoader
anchors.fill: parent
anchors.margins: 60
source: "../dynamic.qml"
}我认为QML引擎缓存dynamic.qml文件。因此,每当我想重新加载加载器时,它都会显示旧的内容。有什么建议吗?
发布于 2013-10-26 08:58:59
在将加载器trimComponentCache()属性设置为空字符串后,需要在QQmlEngine上调用source。换言之:
helpLoader.source = "";
// call trimComponentCache() here!!!
helpLoader.source = "../dynamic.qml";为了做到这一点,您需要向QML公开一些C++对象,该对象具有对您的QQmlEngine的引用(在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";发布于 2016-08-10 21:22:44
我希望有一个纯粹的QML解决方案。我注意到loader.source是一个url (file:///),并记住了如何在请求中使用?t=Date.now()来避免HTTP缓存。尝试将?t=1234添加到loader.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()
}
}
}https://stackoverflow.com/questions/19604552
复制相似问题