Mart

a cute little home a cute little boy a cute little cow: mooo!

Tale of a little pixel

a cute little girl

Lazy loading QML

What is one of the most important things while writing a QML UI? the answer is pretty easy: KISS.

There are several reasons: the first is of course a reason that is pretty valid in any UI in general: the more an interface is simple, the less visual elements there are, the less redundancy, the more elegant and easy it looks (attention: it does not mean less features, it means just better design in their representation)

And second, of course the more objects are on the screen, the more memory is taken for their representation, sometimes a non negligible quantity.

Another thing that is very important is to actually load your interface only for the things that you are actually showing right now on the screen, anything that is hidden, or can be shown just eventually, should be instantiated only just before actually showing, otherwise you are paying in startup time and memory for some objects that may even never be actually shown to the user.

A typical example is a tabbar with maybe 10 pages, if those pages aren't performing an important background task (like loading an html page) why bother loading them?

I've just added a new very simple QML component in org.kde.plasma.extras: ConditionalLoader.

It works pretty much like a standard loader: you specify a source component and it instances it, but just when a certain condition is satisfied, so for instance:

 import QtQuick 1.1
 import org.kde.plasma.components 0.1 as PlasmaComponents
 import org.kde.plasma.extras 0.1 as PlasmaExtras

 Item {
     PlasmaComponents.TabBar {
        PlasmaComponents.TabButton {
             text: "foo"
             tab: fooTab
        }
        PlasmaComponents.TabButton {
             text: "bar"
             tab: barTab
        }
        PlasmaComponents.TabButton {
             text: "baz"
             tab: bazTab
        }
    }

    PlasmaComponents.TabGroup {
        id: tabGroup
        PlasmaExtras.ConditionalLoader {
            id: fooTab
            when: tabGroup.currentTab == fooTab
            //source can be a path name as well
            source: Qt.createComponent("Foo.qml")
        }
        PlasmaExtras.ConditionalLoader {
            id: barTab
            when: tabGroup.currentTab == barTab
            source: Qt.createComponent("Bar.qml")
        }
        PlasmaExtras.ConditionalLoader {
            id: bazTab
            when: tabGroup.currentTab == bazTab
            source: Qt.createComponent("Baz.qml")
        }
    }
 }

In this example (simplified, without anchors and whatnot) the content of the tabs is in separated files, and they will get loaded only when the tab will become the current.

It may be used also to do other stuff, like in PopupApplets to load some things only when the popup gets open for the first time, or in delegates of listviews to load extra ui parts when the user clicks on an item, or whatever many other uses.



Submit comment



Article: