1

currently I have a Repeater Item which loads a delegate from an external file (PeriodicTableDelegate.qml). Is it possible to choose between lets say two different Delegates using Javascript logic? Maybe like this for example:

Normal :

Repeater {
    model: elementModel
    
    delegate: PeriodicTableDelegate {
    height: gridview.cellHeight
    selectionModel: itemSelectionModel
    width: gridview.cellWidth
    x: (group - 1) * width
    y: (period - 1) * height
    }          
}                  
               

How I would want it to work:

Repeater {
    model: elementModel
    
    delegate: pickDelegate() ? PeriodicTableDelegate : SomeOtherDelegate {
    height: gridview.cellHeight
    selectionModel: itemSelectionModel
    width: gridview.cellWidth
    x: (group - 1) * width
    y: (period - 1) * height
    }          
}
function pickDelegate(){
   return window.height > 60
}
PatrickRKa
  • 21
  • 4

2 Answers2

2

The answer is yes. As mentioned in the comments, there are lots of ways to do it, but what you wrote in your question is already almost working. The only thing missing is you probably want to declare your delegates as Components. And while a function can work for your conditional, it makes more sense to use a declarative style relying on property bindings.

Component {
    id: periodic
    PeriodicTableDelegate {
        // initialize stuff
    }
}

Component {
    id: other
    SomeOtherDelegate {
        // initialize stuff
    }
}

property bool someCondition: window.height > 60

Repeater {
    model: elementModel
    delegate: someCondition ? periodic : other
}
JarMan
  • 7,589
  • 1
  • 10
  • 25
1

There's a number of ways of choosing a delegate at runtime. There's (1) DelegateChooser, (2) Loader, (3) QFileSelector, and so on. Then there's the model itself. It really depends.

In the following application I render the periodic table in either landscape or portrait mode. In the default portrait case, I render it with "PeriodicTableDelegate.qml". In the latter case, to fit the periodic table, I render it with "PeriodicTableDelegateLandscape.qml" and rotate the controls by 90 degrees. To switch between these delegates, I make use of Loader.source.

I spent extra effort with populating the ListModel so that element, atomic_id, group, period and bkcol are derived.

import QtQuick
import QtQuick.Controls
Page {
    id: page
    Repeater {
        model: periodicTable
        delegate: Loader {
            source: page.width >= page.height
            ? "PeriodicTableDelegate.qml"
            : "PeriodicTableDelegatePortrait.qml"
        }
    }
    ListModel {
        id: periodicTable
        property string element_definition: `H He
Li Be B C N O F Ne
Na Mg Al Si P S Cl Ar
K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe
Cs Ba La Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
Fr Ra Ac Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og
Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu
Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr`
        property var element_info: {
            "He": { group: 17 },
            "B": { group: 12 },
            "Al": { group: 12 },
            "Hf": { atomic_id: 72 },
            "Ce" : { atomic_id: 58, group: 3 },
            "Th" : { atomic_id: 90, group: 3, inc_period: true },
            "Rf" : { atomic_id: 104 }
        }
        Component.onCompleted: {
            let atomic_id = 1; 
            let group = 0;
            let period = 0;
            for (let element of element_definition.split(/\s+/g)) {
                let info = element_info[element];
                if (info) {
                    atomic_id = info.atomic_id || atomic_id;
                    group = info.group || group;
                    if (info.inc_period) period++;
                }
                let bkcol = "#246";
                if (group === 0 && period) bkcol = "#255";
                if (group === 1) bkcol = "#634";
                if (group >= 5) bkcol = "#446";
                if (group >= 12) bkcol = "#254";
                if (group - period >= 12) bkcol = "#246";
                if ("B,Si,Ge,As,Sb,Te,".indexOf(element + ",") >= 0) bkcol = "#542";
                if (group === 17) bkcol = "#644";
                if (atomic_id >= 109) bkcol = "#445";
                if (period === 7) bkcol = "#047";
                if (period === 8) bkcol = "#632";
                append({atomic_id,group,period,element,bkcol});
                ++atomic_id;
                if (++group === 18) {
                    group = 0;
                    period++;
                }
            }
        }
    }
}

// PeriodicTableDelegate.qml
import QtQuick
import QtQuick.Controls
Rectangle {
    property int cell_width: page.width / 18
    property int cell_height: page.height / 9
    x: group * cell_width
    y: period * cell_height
    width: cell_width - 2
    height: cell_height - 2
    color: bkcol
    Text {
        anchors.centerIn: parent
        text: element
        color: "white"
    }
    Text {
        x: 4
        y: 4
        text: atomic_id
        font.pointSize: 7
        color: "white"
    }
}

// PeriodicTableDelegatePortrait.qml
import QtQuick
import QtQuick.Controls
Rectangle {
    property int cell_width: page.width / 9
    property int cell_height: page.height / 18
    x: period * cell_width
    y: (17 - group) * cell_height
    width: cell_width - 2
    height: cell_height - 2
    color: bkcol
    Text {
        anchors.centerIn: parent
        text: element
        color: "white"
        rotation: -90
    }
    Text {
        x: 4
        y: 4
        text: atomic_id
        font.pointSize: 7
        color: "white"
        rotation: -90
    }
}

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75