dtech
dtech

Reputation: 49289

How to most correctly / efficiently refresh an Item whose source has changed?

I have a loaded qml file from the file system that changes, however since the first time it is loaded it is also cached, it doesn't refresh even if the Loader is "reset" via setting the source component to undefined.

A similar questions has been asked before, however I'd like to go further for a few reasons:

This function causes the property metadata of all components previously loaded by the engine to be destroyed. All previously loaded components and the property bindings for all extant objects created from those components will cease to function.

This certainly sounds ominous, especially the part in bold, since I am not reloading my entire application, it is just a tiny part of a rather big application, which needs to remain in tact while at the same time refreshing that particular external qml file to reflect its changes.

The second part thou sounds a bit more promissing:

This function returns the engine to a state where it does not contain any loaded component data. This may be useful in order to reload a smaller subset of the previous component set, or to load a new version of a previously loaded component.

Once the component cache has been cleared, components must be loaded before any new objects can be created.

So it does give the impression that this method can be used to only reload a subset without breaking the existing code. However, even if that is the case, it will involve a lot of extra work to rebuild all caches for newly instantiated objects, rather than simply cleaning the cache for the particular qml source that changes.

Additionally, I've been thinking about a more complex solution, involving the creation of a custom QML element, which is essentially a wrapper around a whole new QML engine that renders to an FBO and displays the output as an object in my "main" engine, thereby completely isolating the two engines. However I am not all that keen on doing all that extra work, and introducing the overhead of another whole running engine.

So any ideas?

Upvotes: 1

Views: 2218

Answers (1)

dtech
dtech

Reputation: 49289

Until someone comes with a better solution, I have meanwhile discovered that trimComponentCache() fails only if the clearing, trimming and resetting happen sequentially, that is in the same event loop cycle. It works every time if the event loop is allowed to spin in between, so I went for this solution, which works every time:

  Timer {
    id: updater
    interval: 1
    repeat: true
    property int s: 0
    onTriggered: {
      switch (s) {
      case 0:
        loader.sourceComponent = undefined
        ++s
        break
      case 1:
        Aux.trim()
        ++s
        break
      case 2:
        loader.source = "file:/d:/Rect.qml"
        s = 0
        stop()
      }
    }
  }

So the update is issued by starting the timer, it will clear the loader in one cycle, trim the cache in the next, and reload the source and stop in the last, resetting both the loader and its state.

Upvotes: 1

Related Questions