How to use QML Repeater for page indicator? - qml

Below is part of my code. It's working fine, however I spent a lot of time trying to solve it with Repeater to be more elegant and flexible, but couldn't.
Could you please suggest a solution to me? The areaMachine is in an other qml file.
Row {
id: pageIndicatorBoxes
anchors.centerIn: pageIndicatorLine
spacing: 5
Rectangle {
id: pageIndicatorBox1
width: 10
height: 10
color: areaMachine.page == 1 ? "#e5e5e5" : "#404040"
}
Rectangle {
id: pageIndicatorBox2
width: 10
height: 10
color: areaMachine.page == 2 ? "#e5e5e5" : "#404040"
}
Rectangle {
id: pageIndicatorBox3
width: 10
height: 10
color: areaMachine.page == 3 ? "#e5e5e5" : "#404040"
}
Rectangle {
id: pageIndicatorBox4
width: 10
height: 10
color: areaMachine.page == 4 ? "#e5e5e5" : "#404040"
}
}

Looks like you haven't look into the documentation about Repeater and its main delegate property. There you can find code examples that fits your problem, so you can combine it and have something like:
Row {
id: pageIndicatorBoxes
anchors.centerIn: pageIndicatorLine
spacing: 5
Repeater {
model: 4
Rectangle {
id: pageIndicatorBox1
width: 10
height: 10
color: (areaMachine.page === (index + 1)) ? "#e5e5e5" : "#404040"
}
}
}

Related

How to pass an array of color for rectangle in qml

I want to pass the colorModelData for rectangle shown below.
Requirement is: on click of button i want to open a popup. And inside popup want to display multiple number of circles with different colors. Using button can i create a popup which will give me list of colors? ALso list of color should be exposed from outside.
How can i do it?
Rectangle {
id: control
property var colorModelData: ["Red", "Green", "Blue"]
Button{
id: btn
width: 100
height: 100
onClicked: {
rect.visible = true
}
}
Rectangle{
id: rect
visible: false
width: 400
height: 300
color: "gray"
anchors.top: btn.bottom
GridView{
width: rect.width
height: rect.height
model: colorModelData
delegate: Column{
Rectangle {
width: 20
height: 20
radius: width/2
//color: colorModelData [..... getting error]
}
}
}
}
}
I tested your code and it works for me. So I assume the only part you're missing is the line you have commented out. Use this:
color: colorModelData[index]

How to switch focus automatically when max length reached in QML TextField?

In order to do that, I understand I need to use some if condition like the one below. But it looks like I did a mistake!
Is the problem in the if condition or in the position, where should I include it?
Grid {
x: 5
y: 3
rows: 5
columns: 20
spacing: 10
Repeater {
id: rpt
model: 50
TextField {
width: 28
height: 50
color: "green"
text:{ "0000";
if(rpt.itemAt(index).text.length ==4)nextItemInFocusChain().forceActiveFocus()
}
font.pixelSize: 12
Keys.onEnterPressed: nextItemInFocusChain().forceActiveFocus()
validator: IntValidator {
bottom: -256
top: 256
}
}
}
}
You want to react when the text changes inside the TextInput, so in the body of the textChanged signal handler:
TextField {
width: 28
height: 50
color: "green"
onTextChanged: {
if (text.length === 4) {
nextItemInFocusChain().forceActiveFocus()
}
}
}
See more on JavaScript Expressions in QML Documents.

Unable to position custom styled Tumbler

I am trying to give a Tumbler my own style. I declare the Tumbler like this:
Tumbler {
style: MyTumblerStyle {}
height: UIConstants.smallFontSize * 10
width: UIConstants.smallFontSize * 3
TumblerColumn {
model: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
}
}
where MyTymblerStyle is defined like this:
TumblerStyle {
id: root
visibleItemCount: 5
background: Rectangle {}
foreground: Item {}
frame: Item {}
highlight: Item {}
delegate: Item {
id: delRoot
implicitHeight: (control.height) / root.visibleItemCount
Item {
anchors.fill: parent
Text {
text: styleData.value
font.pixelSize: UIConstants.smallFontSize
font.family: UIConstants.robotoregular
anchors.centerIn: parent
scale: 1.0 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6
color: styleData.current?UIConstants.color:"black"
opacity: 1 - Math.abs(styleData.displacement/(root.visibleItemCount-3))
}
}
}
}
I use it in a Row like this:
Row {
MyTumbler {}
StandardText {
color: UIConstants.color
text: "Uhr"
}
}
Now, the result looks like this:
As you can see, the "Uhr" text center is aligned to the top of the Tumbler. Also the Row does not seem to recognize the real width of the Tumbler.
Why? It does work when I do not use MyTumblerStyle.
The problem isn't your style, it's the width assignment.
It helps to break out the Rectangles at a time like this:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Extras 1.3
ApplicationWindow {
title: qsTr("Hello World")
width: 300
height: 600
visible: true
Column {
anchors.centerIn: parent
Tumbler {
id: tumbler
width: 30
TumblerColumn {
model: 25
}
Component.onCompleted: print(width, height, implicitWidth, implicitHeight)
}
Rectangle {
width: tumbler.implicitWidth
height: tumbler.implicitHeight
color: "transparent"
border.color: "blue"
Text {
text: "Tumbler implicit size"
anchors.fill: parent
wrapMode: Text.Wrap
}
}
Rectangle {
width: tumbler.width
height: tumbler.height
color: "transparent"
border.color: "blue"
Text {
text: "The size you gave"
anchors.fill: parent
wrapMode: Text.Wrap
}
}
}
}
(I don't have access to UIConstants, so I guess the width you set)
The implicitWidth of Tumbler is calculated based on the width of each individual TumblerColumn. This allows you to set individual widths for columns, something that is necessary for scenarios where some are wider than others, for example:
So, you should also set the width of your column, or, preferably, only set the width of your column, and not the entire Tumbler:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Extras 1.3
ApplicationWindow {
width: 300
height: 600
visible: true
Row {
anchors.centerIn: parent
Tumbler {
id: tumbler
TumblerColumn {
model: 25
width: 30
}
}
Text {
text: "Uhr"
}
}
}
This also explains why the Text is weirdly positioned; the Row sees 30 pixels, but the column still has its original (much wider) width.

How to change the spacing between items in a Column or Row

I am aligning Items using Column and Row types in QML. Is there any way to give different spacing to each Item. Something along the line of the following:
like:
item1
spacing:10
item2
spacing:20
item3
spacing:40
item4
here is my code:
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
id: rect
anchors.fill: parent
Column{
id: column
anchors.centerIn: parent
spacing: 10
Row{
id: row1
anchors.horizontalCenter: parent.horizontalCenter
Rectangle{
width: 300
height: 100
color: "lightgreen"
}
}
Row{
id: row2
anchors.horizontalCenter: parent.horizontalCenter
Rectangle{
width: 100
height: 50
color: "lightblue"
}
}
Row{
id: row3
anchors.horizontalCenter: parent.horizontalCenter
Rectangle{
width: 50
height: 50
color: "green"
}
}
}
}
}
The hacky version with spacer Items
Sometimes I prefer this over ColumnLayout since in some situations I just can't use ColumnLayout (can't explain exactly why though at the moment).
I get it working as follows
Column {
Rectangle {
// ...
}
Item {
width: 1 // dummy value != 0
height: 10
}
Rectangle {
// ...
}
Item {
width: 1 // dummy value != 0
height: 20
}
Rectangle {
// ...
}
}
An Item of width 0 won't work. I suggest putting a Spacer_Col.qml (and Spacer_Row analog) into you Toolbox, looking something like
import QtQuick 2.8
Item {
id: root
property alias spacing: root.height
width: 1 // dummy value different from 0
}
Using ColumnLayout
ColumnLayout {
Rectangle{
// ...
}
Rectangle{
Layout.topMargin: 10
// ...
}
Rectangle{
Layout.topMargin: 20
// ...
}
}
By nesting each rectangle you want to space, as follows;
Row {
spacing: 20
Rectangle { color: "red"; width: 50; height: 50 }
Row {
spacing: 50
Rectangle { color: "green"; width: 20; height: 50 }
Row {
spacing: 100
Rectangle { color: "blue"; width: 50; height: 20 }
}
}
}
Different spacings in a row

Qml nested row/repeater in a column/repeater

I am trying to create two rows of rectangles using a row/repeater within a column/repeater. The results I am seeing are that the rows of rectangles are stacked on top of each other. I expected to see a blue row of rectangles with a green row of rectangles beneath the blue row. It seems like this should be possible. Any ideas on what I am doing wrong?
I think a code example will help illustrate what I am trying to accomplish.
Here is my main.qml
import QtQuick 2.2
Rectangle {
visible: true
width: 640
height: 480
color: 'black'
border.color: 'white'
RectRow {
id: rectRow
startX: 10
startY: 10
rectVals: [{count: 4, color: 'blue'}, {count: 2, color: 'green'}]
}
}
Here is my RectRow.qml
import QtQuick 2.2
Item {
property var rectVals
property alias startX: rectCol.x
property alias startY: rectCol.y
property string rectBorderColor: '#ffffff'
Column {
id: rectCol
Repeater {
id: repeater
model: rectVals
Item {
height: 50
Row {
property string rectColor: modelData.color
Repeater {
model: modelData.count
Rectangle {
width: 100
height: 50
color: parent.rectColor
border.color: rectBorderColor
}
}
}
}
}
}
}
As in QML Form layout (GridLayout) troubles, you need to give the Item a width:
import QtQuick 2.2
Item {
property var rectVals
property alias startX: rectCol.x
property alias startY: rectCol.y
property string rectBorderColor: '#ffffff'
Column {
id: rectCol
Repeater {
id: repeater
model: rectVals
Item {
width: row.width
height: 50
Row {
id: row
property string rectColor: modelData.color
Repeater {
model: modelData.count
Rectangle {
width: 100
height: 50
color: parent.rectColor
border.color: rectBorderColor
}
}
}
}
}
}
}
Or just remove it altogether; it doesn't seem to be necessary.