Spinbox change values on keypress in qml - qt

Is it possible to automatically change the value of the spinbox on keypress instead of enter? The problem is the following, lets suppose we go to the input where we have the number one:
And now i change it to number 10, but dont click on enter:
Now i click on the plus sign and it goes to number two:
How can this be changed in a way that when i loose focus, or click in the minus or plus sign of the spinbox in automatically takes in account the last digited number?
This is what is happening with QtQuick.Controls 2.0
An example:
import QtQuick 2.9
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
height: 200
width: 400
Item {
id: page
anchors.fill: parent
width:parent.width
height: parent.height
Column{
width:parent.width
spacing:10
SpinBox {
id: spinBox1
width: 100
height: 30
stepSize: 1
editable: true
}
}
}
}

You could use the property "contentItem" of SpinBox and adding a TextInput.
The TextInput has the signal handler "onTextChanged".
SpinBox {
id: spinbox
value: 10
editable: true
contentItem: TextInput {
text: spinbox.textFromValue(spinbox.value, spinbox.locale)
font: spinbox.font
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !spinbox.editable
validator: spinbox.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
onTextChanged: {
spinbox.value = parseInt(text);
}
}
}

Related

How to have a numerical model start at 1 in a combobox from QML

In the combobox from qml we can give them a model with a numerical value.
The options of the combobox then start from 0 to the model value minus 1.
What i want is to show the values on the combobox plus 1.
But still, if i try to access, with qml javascript, the value that is selected in that combobox is the original value, what i mean is, if it's the first option it's the value 0. The numbers shall only start from 1 in the display part of combobox.
I'm going to give an example (with a model=32):
display of the combobox
the options:
what i want is them to start at one, like this:
The code used was the following:
import QtQuick 2.9
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
height: 200
width: 400
Item {
id: page
anchors.fill: parent
width:parent.width
height: parent.height
Column{
width:parent.width
spacing:10
ComboBox {
id:comboBox
model: 32
objectName: "test"
implicitHeight: 30
displayText: currentText
// delegate:
// Button {
// id:buttonCombo
// width: parent.width
// text: index+1
// height:40
// contentItem: Text {
// text: buttonCombo.text
// font: comboBoxCustom.font
// leftPadding: 5
// horizontalAlignment: Text.AlignLeft
// verticalAlignment: Text.AlignVCenter
// elide: Text.ElideRight
// }
// background: Rectangle {
// color: buttonCombo.hovered ? (buttonCombo.pressed ? "#d8d8d8" : "#e8e8e8" ) : "#fff"
// }
// }
anchors.topMargin: 10
}
}
}
}
Maybe this could be done:
displayText: Number(currentText)+1
but i don't know if its the best solution...

How to change the page to the next or previous item of a SwipeView by clicking on the right and left arrow respectively?

I have a SwipeView that loads its internal elements through a Repeater and a Loader.
I would like to swipe between the items forward and backward by just clicking the arrows on the right and left of the SwipeView.
How can I implement this behavior in QML?
SwipeView {
id: __swipeView
Layout.fillHeight: true
Layout.fillWidth: true
Repeater {
model: 3
Loader {
source: "qrc:/../SwipeDelegate.qml"
}
}
}
Within your delegate, you can access the SwipeView via the SwipeView attached property, and then increment or decrement the current index as necessary:
import QtQuick 2.6
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
SwipeView {
anchors.fill: parent
Repeater {
model: 3
Item {
id: delegate
Button {
text: "<"
enabled: index > 0
onClicked: delegate.SwipeView.view.decrementCurrentIndex()
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
}
Label {
text: "Page " + (index + 1)
anchors.centerIn: parent
}
Button {
text: ">"
enabled: index < delegate.SwipeView.view.count - 1
onClicked: delegate.SwipeView.view.incrementCurrentIndex()
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
It's important to use the functions as opposed to setting currentIndex directly, for the reasons described here.

Qt QML How to change size of a component and get the whole page change

I am working on an android application and I am facing a problem. In a page of the application I have some input fields, one of them is for date and I wanted to add a Calendar that open on demand for selecting the date or just enter the date manually, for this, I created a custom component which is composed of a TextInput and a button which when clicked will create the calendar item with a loader and set the size of the loader to 80 (it was 0 initially) all this components are included in a columnlayout. When the button get clicked the calendar is drawn below the other input fields.
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
FocusScope {
id: root
Layout.preferredHeight: 20
property alias text: input.text
property alias border: background.border
property alias backgroundColor: background.color
property alias textColor: input.color
ColumnLayout{
anchors.fill: parent
spacing: 1
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
Rectangle {
id: background
Layout.fillHeight: true
Layout.fillWidth: true
color: "darkgrey"
TextInput {
id: input
anchors.fill: parent
anchors.margins: 3
verticalAlignment: TextInput.AlignVCenter
focus: true
text: dateInput.selectedDate
}
}
CustomButton {
id: calandar
Layout.fillHeight: true
Layout.preferredWidth: 40
image: "icons/CalandarButton.svg"
onClicked: {
console.log("clicked calandar")
if(calendarLoader.status === Loader.Null){
calendarLoader.height = 80
calendarLoader.sourceComponent = Qt.createQmlObject("import QtQuick 2.5; import QtQuick.Controls 1.4; Calendar {}",
calendarLoader,
"calandarpp")
}
else{
calendarLoader.height = 0
calendarLoader.sourceComponent = undefined
}
}
}
}
Loader {
id: calendarLoader
Layout.fillWidth: true
height: 0
}
}
}
If something is below, then try changing its z coordinate.
There is no need to do Qt.createQmlObject() ever. It's enough to toggle Loader.active or Item.visible.
Example is not reproducible, make sure that it runs by itself with qmlscene.
This works for me:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
FocusScope {
id: root
Layout.preferredHeight: 20
property alias text: input.text
property alias border: background.border
property alias backgroundColor: background.color
property alias textColor: input.color
z: 1
Loader {
id: calendarLoader
active: false
sourceComponent: Calendar {}
z: 1
}
ColumnLayout {
anchors.fill: parent
spacing: 1
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
Rectangle {
id: background
Layout.fillHeight: true
Layout.fillWidth: true
color: "darkgrey"
TextInput {
id: input
anchors.fill: parent
anchors.margins: 3
verticalAlignment: TextInput.AlignVCenter
focus: true
}
}
Button {
id: calandar
Layout.fillHeight: true
Layout.preferredWidth: 40
onClicked: {
console.log("clicked calandar")
calendarLoader.active = !calendarLoader.active
}
}
}
}
}

How to ensure Button has focus when QML tab is activated, rather than TextField?

In QML, I have a Tab containing a TextField and a Button. How do I ensure the Button has focus when the tab is selected, instead of the TextField? Setting "focus:" to true and false, respectively, does not do it. In the code below, the goal is for btnRefresh to have focus when a tab is selected, instead of txtName.
main.qml:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2 // For TabViewStyle
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TabView {
id: tabView
anchors.fill: parent
anchors.margins: 20
tabPosition: Qt.BottomEdge
Tab {title: "Tab 1"; source: "mytab.qml"}
Tab {title: "Tab 2"; source: "mytab.qml"}
style: TabViewStyle {
frameOverlap: 1
tab: Rectangle {
color: styleData.selected ? "steelblue" :"lightsteelblue"
border.color: "steelblue"
implicitWidth: Math.max(text.width + 4, 80)
implicitHeight: 20
radius: 2
Text {
id: text
anchors.centerIn: parent
text: styleData.title
color: styleData.selected ? "white" : "black"
}
}
frame: Rectangle { color: "steelblue" }
}
}
}
mytab.qml:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Rectangle {
anchors.fill: parent
GridLayout {
columns: 2
anchors.fill: parent
rowSpacing: 10
RowLayout {
Layout.columnSpan: 2
Label {
id: lblName
text: "Name:"
}
TextField {
id: txtName;
text: "a name"
Layout.preferredWidth: lblName.implicitWidth * 1.5;
focus: false
}
}
TextArea {
id: textSetup
text: "Text Area"
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.fillHeight: true
}
Button {
id: btnRefresh
Layout.columnSpan: 2
Layout.alignment: Qt.AlignHCenter
text: qsTr("Refresh")
focus: true
}
}
}
Whenever you switch tabs in a TabView, a signal handler onVisibleChanged is called on the two tabs (one that disappeared and the one that appeared) since the visibility of these tabs has changed. You can try adding following code to your Tabs:
Tab {
id: tab1
title: "Tab 1"; source: "mytab.qml"
onVisibleChanged: {
if (visible) tab1.item.funcSetFocusOnButton();
}
}
Please note the way a function is called on a tab using item.
Now in "mytab.qml", you create a javascript function funcSetFocusOnButton which sets focus on your button. So your mytab.qml will have this additional code:
Rectangle {
//Your GridLayout{}
funcSetFocusOnButton() {
btnRefresh.forceActiveFocus();
}
}
Note here that the function funcSetFocusOnButton should be a direct child of your base item (rectangle here). Hope this helps!

QML ListView current item not changing with keystrokes or mouse

I have a very simple ListView.
ListView {
id: logListView
anchors.fill: parent
model: LogEntryListModel
delegate:
Text {
text: "Log Item: " + timestamp + ", " + verb
}
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
clip: true
}
It shows the model fine and highlights the first item. It does not move the highlight when I click on another item nor when I use the arrow keys. I know how to control the highlighted item manually by adding event handlers but I see references in the docs to automatic handling of the selectedItem. I was wondering:
Does QML provide an automatic changing of the selected item highlighting? What do I need to add to turn it on?
The keyboard handling is done automatically:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 400
height: 400
ListView {
id: logListView
anchors.fill: parent
model: 10
delegate: Text {
text: "Log Item: " + modelData
}
highlight: Rectangle {
color: "lightsteelblue";
radius: 5
}
focus: true
clip: true
}
}
If using the up and down arrow keys does not change the selected item for you, using the code above, then it's a bug.
Using a mouse to select items is not handled by default, however; only flicking/dragging of the list is. It's easy to add, though:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 400
height: 400
ListView {
id: logListView
anchors.fill: parent
model: 10
delegate: Text {
text: "Log Item: " + modelData
MouseArea {
anchors.fill: parent
onClicked: logListView.currentIndex = index
}
}
highlight: Rectangle {
color: "lightsteelblue";
radius: 5
}
focus: true
clip: true
}
}

Resources