[SailfishDevel] ComboBox init

François KUBLER francois at kubler.org
Mon Sep 8 19:22:49 UTC 2014


Hi :)

I have a ComboBox issue !

The ComboBox I want to use is made of dynamic items. I build it with a 
ListModel and a Repeater as follow :

ComboBox {
     id: project

     label: qsTr("Project")
     menu: ContextMenu {
         MenuItem { text: qsTr("Not set") }

         Repeater {
             model: ProjectsModel { id: projects }
             delegate: MenuItem { text: model.value }
         }
     }
}

It works pretty well (yay QML !).

Now I would like to initialize the ComboBox value. I tried several 
things (see after) and none of them worked. I hope you guys can give me 
some help/tip :)

1. First I tried to set its value directly. It doesn't really work well 
: the text that appears is the good one, but when I open the ComboBox to 
chose another value, the highlighted item is not the good one (which 
means that the ComboBox doesn't compute currentIndex and currentItem 
automagically when one set the ComboBox value). Moreover, when I select 
another item in the menu, the currentIndex and currentItem are changed 
as expected, but the value of the ComboBox doesn't change ! Here is the 
code that highlights the problem :

ComboBox {
     id: project

     label: qsTr("Project")
     menu: ContextMenu {
         MenuItem { text: qsTr("Not set") }

         Repeater {
             model: ProjectsModel { id: projects }
             delegate: MenuItem { text: model.value }
         }
     }

     value: "Some Value"

     onCurrentIndexChanged: {
         console.log("currentIndex just changed to : ", currentIndex);
     }

     onCurrentItemChanged: {
         console.log("currentItem just changed to : ", currentItem.text);
     }

     onValueChanged: {
         console.log("value just changed to : ", value);
     }
}

And the output :

[D] onValueChanged:159 - value just changed to : Foo
[...]
[D] onCurrentItemChanged:155 - currentItem just changed to :  Bar
[D] onCurrentIndexChanged:151 - currentIndex just changed to :  2

What I expected to see :

[D] onValueChanged:159 - value just changed to : Foo
[...]
[D] onCurrentItemChanged:155 - currentItem just changed to :  Bar
[D] onCurrentIndexChanged:151 - currentIndex just changed to :  2
[D] onValueChanged:159 - value just changed to :  Bar



2. Then I tried to set currentIndex. There, for some reason that I don't 
explain, it seems that the ComboBox always reset it to 0 :

Component {

     // Some other stuff here

     ComboBox {
         id: project

         label: qsTr("Project")
         menu: ContextMenu {
             MenuItem { text: qsTr("Not set") }

             Repeater {
                 model: ProjectsModel { id: projects }
                 delegate: MenuItem { text: model.value }
             }
         }

         onCurrentIndexChanged: {
             console.log("currentIndex just changed to : ", 
currentIndex);
         }

         onCurrentItemChanged: {
             console.log("currentItem just changed to : ", 
currentItem.text);
         }

         onValueChanged: {
             console.log("value just changed to : ", value);
         }
     }

     Component.onCompleted: {
         // Here I get the task object from the database.
         var task = Storage.getTask(id);

         if(task !== null)
         {
             for(var i=0 ; i<projects.count ; i++)
             {
                 if(task.project === projects.get(i).value)
                 {
                     project.currentIndex = i + 1;  // We have to +1 
because of the <Not set> MenuItem.
                     break;
                 }
             }
         }
     }
}

And the output :

[D] onCurrentIndexChanged:151 - currentIndex just changed to :  2
[D] onCurrentIndexChanged:151 - currentIndex just changed to :  0


Do you guys have any idea on what's going on ?


By the way, I think it could be great for the ComboBox to behave like 
HTML’s <select> :
MenuItem could have a text and a value property. Setting a ComboBox 
value would automatically update currentItem and currentIndex. Something 
like this :

ComboBox {
     menu: ContextMenu {
         MenuItem {
             text: qsTr("Some item")
             value: "some_item"
         }
	MenuItem {
             text: qsTr("Another item")
             value: "another_item"
         }
     }

     Component.onCompleted: {
         value = "another_item";		// This would highlight the second 
item, set currentIndex to 1 and currentItem accordingly.
     }
}

Of course, one could still set currentIndex or currentItem, and it would 
update everything accordingly.
Also, the MenuItem value would default to the text value if the value is 
not explicitly set.

I'd be glad to work on this if you agree :)


Thanks for your attention.

My best wishes,

-- 
François



More information about the Devel mailing list