Reputation: 63
I have a ListModel which elements have information about a data type. I'm using this in a Repeater to show a label and a component according to the datatype, but I don't know how to change that TextField (in the case of "TEXT" datatype) with a; e.g. a button to call a file dialog in the case of "IMAGE"; or a TextField with a mask for double in the case I get datatype "REAL". How can I make this?
Here is my code:
Repeater {
id: r2
model: ListModel {
ListElement {
nombreCampo: "Name"
datoValor: "John Doe"
tipoDato: "TEXT"
}
ListElement {
nombreCampo: "Birth Date"
datoValor: "19910101"
tipoDato: "DATE"
}
ListElement {
nombreCampo: "Photo"
datoValor: "whatever.jpg"
tipoDato: "IMAGE"
}
ListElement {
nombreCampo: "Height"
datoValor: "1.55"
tipoDato: "REAL"
}
}
Text {
text: nombreCampo
}
// this would go well with "TEXT" but not with "DATE" (where I'd prefer a datepicker)
// or with "IMAGE" (where I'd prefer a button to call a file dialog).
// so this is the part where I need to generate it according to the case
TextField {
text: datoValor
placeholderText: nombreCampo
onTextChanged: {
r2.model.get( index ).datoValor = this.text;
}
}
}
Thanks in advance.
Upvotes: 1
Views: 2370
Reputation: 2149
I would use a loader inside your delegate.
Column{
Repeater{
model: // your model
delegate: Loader{
anchors{
right: parent.right
left: parent.left
}
sourceComponent: {
if(tipoDato=== "TEXT") {return textFieldComponent;}
else if(tipoDato=== "DATE") {return datePickerComponent;}
else if(tipoDato=== "IMAGE"){return imagePickerPickerComponent;}
else if(tipoDato=== "REAL") {return floatPickerComponent;}
}
}
}
}
// Component definition
Component{
id: textFieldComponent
// Define your component here
}
Component{
id: datePickerComponent
// Define your component here
}
Component{
id: imagePickerPickerComponent
// Define your component here
}
Component{
id: floatPickerComponent
// Define your component here
}
If you use this example take into account that each component has to have their height defined and the top parent column has to have their width defined in order to render all the items correctly.
Upvotes: 3
Reputation: 24416
In Qt 5.12 you can use DelegateChooser + DelegateChoice:
import QtQuick 2.7
import QtQuick.Controls 2.3
import Qt.labs.qmlmodels 1.0
ApplicationWindow {
width: 500
height: 500
visible: true
Column {
anchors.fill: parent
Repeater {
id: r2
model: ListModel {
ListElement {
nombreCampo: "Name"
datoValor: "John Doe"
tipoDato: "TEXT"
}
ListElement {
nombreCampo: "Birth Date"
datoValor: "19910101"
tipoDato: "DATE"
}
ListElement {
nombreCampo: "Photo"
datoValor: "whatever.jpg"
tipoDato: "IMAGE"
}
ListElement {
nombreCampo: "Height"
datoValor: "1.55"
tipoDato: "REAL"
}
}
delegate: DelegateChooser {
role: "tipoDato"
DelegateChoice {
roleValue: "DATE"
// delegate: SomeDatePicker {
// date: datoValor
// }
}
DelegateChoice {
roleValue: "IMAGE"
delegate: Button {
text: "Select image"
}
}
DelegateChoice {
roleValue: "TEXT"
delegate: TextField {
text: model.datoValor
}
}
DelegateChoice {
roleValue: "REAL"
delegate: TextField {
text: model.datoValor
// inputMask: ...
}
}
}
}
}
}
In earlier versions, you can use Loader, and choose the source/sourceComponent based on the model data.
Upvotes: 3