Easy way to configure QML combobox with 1-25 - qt

I have a need for a simple drop-down box containing the numbers 1 through 25 inclusive.
If I set the model up as a simple 25, I get the values 0 through 24 inclusive. I know I can have a more complicated list model but it seems rather silly to construct a massive array of values when they should be able to be calculated on the fly.
From what I read, it should be a simple matter to create a delegate for setting the display values but, with the QML:
ComboBox {
width: 100
model: 25
delegate: ItemDelegate {
text: index + 1
}
}
the values in the drop-down selection area are correct but the value displayed on selection are still zero-based.
How do I get both the selection area and the value to be the values 1..25?

You can set the displayText: currentIndex + 1 for the combo box:
ComboBox {
width: 100
model: 25
delegate: ItemDelegate {
text: index + 1
}
displayText: currentIndex + 1
}

Related

QML Listview space items to fill width

I have a ListView (horizontal orientation) in my qml containing some fixed-size elements. I want items to be spaced out to fill the entiew width of ListView element. So if there are less elements I want them to be spaced out more. Basically what I need is exactly like Layout.fillWidth = true property of RowLayout but for ListView.
I can count how many items I have, then subtract total items width from ListView width, divide by items count and assign the spacing but it seems too silly to do.
Is there a way to do this automatically like in RowLayout?
Or maybe I need to use something different from ListView for this? Something like RowLayout but that I can assign my list data model to?
You can accomplish what you want with a ListView, you just need to adjust the spacing dynamically based on how many delegates you have. This example will break down if your delegates are differently-sized (as this is based only on the width of the first delegate), or if the delegates cumulatively exceed the width of the ListView.
ListView {
width: 500
orientation: Qt.Horizontal
model: 6
spacing: {
if (count > 0) {
return (width - (itemAtIndex(0).width * count))/(count - 1)
} else {
return 0
}
}
delegate: Rectangle {
implicitHeight: 50
implicitWidth: 50
color: "red"
border.width: 1
}
}
ListView may not be the most appropriate container for this task. I say this because it has a built in ScrollView and other behaviors that it sounds like you don't need. If all you need is a simple row of a few identically-sized delegates, I agree with scopchanov and believe that a Repeater inside a RowLayout would be the best option. Here is a simple example:
RowLayout {
width: 500
Repeater {
model: 6
delegate: Rectangle {
implicitHeight: 50
implicitWidth: 50
color: "tomato"
border.width: 1
Layout.alignment: Qt.AlignHCenter // must be set to align the rectangles within their empty space
}
}
}
You may notice that this introduces gaps to the left and right, if these gaps are unacceptable, you may need to set the spacing on the RowLayout in the same manner as the ListView example instead.

Nested repeaters does not respect z values

I have two repeaters, one is nested inside of the other.
There are two Rectangles;
Repeater {
model: x
Rectangle {
id: alwaysOnBottom
z: -1
..
}
Repeater {
z: 100
model: y
Rectangle {
id: alwaysOnTop
z: 100
}
}
}
I always want the second rectangle two be on top of the first one.
However, other items just does not respect their z value and, say second item's first rectangle overdraws the first item's second rectangle.

Unique id for each element of a ListView

I have a ListView of Items and I need that each element has an unique id.
But I have two conditions on my Items:
I can't use index because my Itemscan be moved (drag&drop), so their index will change.
Each Item can be displayed many times, so there is no property of these elements that can help me to distinguish them.
My idea was to do something like that:
ListView {
id: list
property int uniqueId: 0
width: 180; height: 200
model: myModel
delegate: Text {
property int uniqueid: list.uniqueId
text: uniqueid
}
Component.onCompleted: list.uniqueId++
}
But it doesn't work because when list.uniqueId is updated, it will update my Items id and they will all have the same id ( id = list.uniqueId)
How could I proceed?
Well, if you severe (or don't create) the binding, it will not auto update:
delegate: Text {
Component.onCompleted: text = uniqueId++
}
However, I don't think avoiding this will really fix your design. What you should do is have the the unique id part implemented all the way back into the model data.

Open QML ComboBox drop down menu from the current item position

I have choose an item in combobox. Item's position is 300 for example. If I want to choose new element from combobox . Popup shows from beginning. I want to popup opened from current item position.
ComboBox {
id: control
model: ["First", "Second", "Third","MERHABA","NASILSIN","SELAM","IYIMISIN","DOSTUM","SUAN","BIR","DENEME YAPILIYOR"]
//width: 350
//font.pixelSize: 20
delegate: ItemDelegate {
width: 350
text: modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
font.pixelSize: 30
highlighted: control.highlightedIndex == index
}
For QtQuick.Controls 2, There is a 'popup' property, so we can set the popup position with it's own property 'y', like this:
ComboBox {
model: ["First", "Second", "Third"]
delegate: ItemDelegate {
text: modelData
}
popup.y: y + height // popup just below ComboBox
}
The ComboBox will work the way you want it if the conditions allow for it, that is, if you have enough elements to fill the entire drop down list after the current index item it will show from that item rather than the beginning.
The stock ComboBox however doesn't seem to allow you to specify the drop down list height, so it will take significantly more elements than you have in your example. Or significantly taller elements.
Furthermore, if the current index is the last element, how do you imagine this will show? The list would show only the last element plus a whole bunch of nothing, which is not even possible, the last item cannot move up from the end of the list.
If you really want that behavior, you will have to implement your own combo box element from scratch.
I was facing the same issue and found out that if you place the popup onOpened, it works perfectly:
ComboBox {
id: yearDropdown
model: yearModel
onActivated: updateVisibleDate()
popup: Popup {
id: comboPopup
clip: true
contentItem: ListView {
id: listView
implicitHeight: contentHeight
model: yearDropdown.popup.visible ? yearDropdown.delegateModel : null
onModelChanged: if(model) positionViewAtIndex(yearDropdown.currentIndex, ListView.Center);
ScrollIndicator.vertical: ScrollIndicator { }
}
onOpened: {
x = yearDropdown.x //Set the position you want
y = yearDropdown.y + yearDropdown.implicitHeight //Set the position you want
}
}
}

How to access nested Repeaters in QML?

I want to fill the colours in the following rectangles created through Repeaters, dynamically.
I am not able to access the bottom Repeater at all.
How should I access "all" the rectangles here?
Row
{
spacing: 20
Repeater
{
id: repeater3
property Repeater repeater2: repeater2
model: head.rows
Column
{
id: columnInBetween
spacing: 20
Repeater
{
id: repeater2
model: head.columns
property Row row1: row1
Row
{
id: row1
property Repeater repeater1: repeater1
Repeater
{
id: repeater1
model: 2
Rectangle
{
width: 20; height: 20
color: "red"
}
}
}
}
}
}
}
Repeater will expand Item they contians.So you can use .children[index] to access those Item expanded.
In your case:
/*0< index < head.rows
you get first Column expanded by repeater3*/
repeater3.itemAt(index).children[0]
/*0< index < head.columns
you get first Row of first Column expanded by repeater3 and repeater2*/
repeater3.itemAt(index).children[0].children[0]
/*0< index < 2
you get first Rectangle of first Row of first Column expanded by repeater3 and repeater2 and repeater1*/
repeater3.itemAt(index).children[0].children[0].children[0]
By the way, I do not know your intention and just remaid that you are getting a head.columns rows and 2 * head.rows columns of tables.

Resources