How to set focus to TextField inside ListView delegate? - qt

I have ListView with some text input fields inside it:
Window {
visible: true
ListModel {
id: textModel
ListElement {
text: "Bill Smith"
}
ListElement {
text: "John Brown"
}
ListElement {
text: "Sam Wise"
}
}
ListView {
width: 180; height: 200
focus: true
model: textModel
delegate: RowLayout{
id: layout
Label {
text: model.text
}
TextField {
text: model.text
}
}
}
}
And I want to set input focus to the first TextField in the list. How can I do this? If I add focus: true in ListView it does not help.

You have to activate the focus of the TextField using the ListView.isCurrentItem property:
ListView {
id: view
width: 180; height: 200
focus: true
model: textModel
delegate: RowLayout{
id: layout
Label {
text: model.text
}
TextField {
focus: layout.ListView.isCurrentItem
text: model.text
}
}
// Component.onCompleted: view.currentIndex = 0
}

Related

I have a ListView where I add and delete ListElements. When I delete a ListElement (row), is there a way to animate the movement of the lower items?

In my ListView, I have an add button which appends a ListElement to the end of the ListView. Each ListElement has a delete button within its row, and when it is clicked, I animate it going away, but I also want to animate any items below when the move up.
ListView {
id: myListView
delegate: myListViewDelegate
model: myListModel
anchors.fill: parent
}
ListModel {
id: myListModel
}
Component {
id: myListViewDelegate
Item {
id: rowContainer
height: 40
width: myListView.width
Text {
id: labelText
text: label
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
}
CustomButton {
anchors {
right: parent.right
rightMargin: 8
verticalCenter: parent.verticalCenter
}
width: 32
height: width
buttonRadius: width/2
iconSource: "qrc:/image/Delete.png"
onReleased: deleteRowAnimation.start()
}
ParallelAnimation {
id: deleteRowAnimation
SmoothedAnimation {velocity: 300; target: rowContainer; properties: "x"; to: -rowContainer.width}
onRunningChanged: if(!running) deleteRow(index)
}
}
}
Later in the code..
function deleteRow(index) {
myListModel.remove(index)
}
I am able to animate the row leaving (being deleted), but if there are rows below it, they jump up to fill the spot where the row was deleted. I would like this to be a smooth, animated transition.
Here's a quick example on how it works:
import QtQuick 2.12
import QtQuick.Controls 2.3
ApplicationWindow {
id: window
visible: true
width: 400
height: 400
title: qsTr('Frameless')
flags: Qt.Window | Qt.FramelessWindowHint
ListView {
id: view
anchors.fill: parent
model: ListModel{
ListElement {text: "111111"}
ListElement {text: "222222"}
ListElement {text: "333333"}
ListElement {text: "444444"}
ListElement {text: "555555"}
ListElement {text: "666666"}
ListElement {text: "777777"}
ListElement {text: "888888"}
}
delegate: Text {
id: name
text: qsTr(modelData)
Rectangle {
anchors.fill: parent
color: "red"
opacity: 0.4
}
}
displaced: Transition {
NumberAnimation { property: "y" duration: 200 }
}
}
Shortcut {
sequence: "Esc"
onActivated: view.model.remove(2)
}
}
On Escape the 3rd element element is being removed and that is triggering the rest of the list to move up.
Possibilities of this are endless. Have fun!

How to make a cell editable in qt tableview

I try to make a cell editable using a tableview in qt. I have found a few examples and came up with the following:
TableView {
id: tableView
objectName: "tableView"
horizontalScrollBarPolicy: -1
selectionMode: SelectionMode.SingleSelection
Layout.minimumWidth: 300
Layout.fillHeight: true
Layout.fillWidth: true
model: trackableInfoModel
itemDelegate: Rectangle {
Text {
anchors.verticalCenter: parent.verticalCenter
text: styleData.value
}
MouseArea {
id: cellMouseArea
anchors.fill: parent
onClicked: {
if(styleData.column === 2){
//do something
}
}
}
}
From what I found it looks like I need an itemDelegate to paint each cell. Then I add a MouseArea to the cell and check which cell was selected. In my case I only need to react on the cells in column 2.
The thing is when I use the code shown above I get the error that:
JavaScipt blocks are not supported in a QT Quick UI form. (M223)
Because of that I tried to register a property alias for cellMouseArea like this:
property alias cellMouseArea : cellMouseArea
However that leads to this error:
qrc:/EditPageForm.ui.qml:24 Invalid alias reference. Unable to find id "cellMouseArea"
Overlay cell with TextInput on click.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TableView {
id: tableView
objectName: "tableView"
horizontalScrollBarPolicy: -1
selectionMode: SelectionMode.SingleSelection
anchors.fill: parent
TableViewColumn {
id: titleColumn
title: "Title"
role: "title"
movable: false
resizable: false
width: tableView.viewport.width - authorColumn.width
}
TableViewColumn {
id: authorColumn
title: "Author"
role: "author"
movable: false
resizable: false
width: tableView.viewport.width / 3
}
model: ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
itemDelegate: Rectangle {
Text {
anchors { verticalCenter: parent.verticalCenter; left: parent.left }
color: "black"
text: styleData.value
}
MouseArea {
id: cellMouseArea
anchors.fill: parent
onClicked: {
// Column index are zero based
if(styleData.column === 1){
loader.visible = true
loader.item.forceActiveFocus()
}
}
}
Loader {
id: loader
anchors { verticalCenter: parent.verticalCenter; left: parent.left}
height: parent.height
width: parent.width
visible: false
sourceComponent: visible ? input : undefined
Component {
id: input
TextField {
anchors { fill: parent }
text: ""
onAccepted:{
// DO STUFF
loader.visible = false
}
onActiveFocusChanged: {
if (!activeFocus) {
loader.visible = false
}
}
}
}
}
}
}
}

QML Nested List view with Highlight

I need to create nested list view and as shown below, and highlight the main list and sub-list with different color
I have tried with ListView highlight but there are issue like the highlight showing for child as well as parent as shown
below image.
I am using the code from here with some minor modification.
Here is the full code
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: loginWindow
//visibility: "Maximized"
visible: true
width: 720
height: 720
Item {
width: 200
height: 720
ListView {
id: list
anchors.fill: parent
model: nestedModel
delegate: categoryDelegate
highlight: Rectangle {
color: "#FF00AAFF" //"#FF59ACFF";
radius: 2
}
}
ListModel {
id: nestedModel
ListElement {
categoryName: "Veggies"
collapsed: true
// A ListElement can't contain child elements, but it can contain
// a list of elements. A list of ListElements can be used as a model
// just like any other model type.
subItems: [
ListElement {
itemName: "Tomato"
},
ListElement {
itemName: "Cucumber"
},
ListElement {
itemName: "Onion"
},
ListElement {
itemName: "Brains"
}
]
}
ListElement {
categoryName: "Fruits"
collapsed: true
subItems: [
ListElement {
itemName: "Orange"
},
ListElement {
itemName: "Apple"
},
ListElement {
itemName: "Pear"
},
ListElement {
itemName: "Lemon"
}
]
}
ListElement {
categoryName: "Cars"
collapsed: true
subItems: [
ListElement {
itemName: "Nissan"
},
ListElement {
itemName: "Toyota"
},
ListElement {
itemName: "Chevy"
},
ListElement {
itemName: "Audi"
}
]
}
}
Component {
id: categoryDelegate
Column {
width: 200
Rectangle {
id: categoryItem
border.color: "black"
border.width: 5
color: "#33FF5225"
height: 50
width: 200
Text {
anchors.verticalCenter: parent.verticalCenter
x: 15
font.pixelSize: 24
text: categoryName
}
Rectangle {
color: "red"
width: 30
height: 30
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
// Toggle the 'collapsed' property
onClicked: {
list.currentIndex = index
nestedModel.setProperty(index, "collapsed",
!collapsed)
}
}
}
}
Loader {
id: subItemLoader
// This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null
// the Loader element retains the same height it had when sourceComponent was set. Setting visible
// to false makes the parent Column treat it as if it's height was 0.
visible: !collapsed
property variant subItemModel: subItems
sourceComponent: collapsed ? null : subItemColumnDelegate
onStatusChanged: if (status == Loader.Ready) item.model = subItemModel
}
}
}
Component {
id: subItemColumnDelegate
Column {
property alias model: subItemRepeater.model
width: 200
Repeater {
id: subItemRepeater
delegate: Rectangle {
x: 10
color: "#33FF5225"
height: 40
width: 190
border.color: "black"
border.width: 2
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
font.pixelSize: 18
text: itemName
}
}
}
}
}
}
}
How can I overcome this issue. Basically I need to highlight Parent and child Item with different color.
Edit:
I can highlight parent list using the code
color:categoryDelegate.ListView.isCurrentItem ? "#FF00AAFF" : "#CCBBBBBB"
but coud'nt a find similar way to change the color of child list (sub list) on click.
Change the color property of the delegate in subItemRepeater to your choice.
Example
Component {
id: subItemColumnDelegate
Column {
...
Repeater {
id: subItemRepeater
delegate: Rectangle {
...
color: "purple"
...
}
}
}
}
Similarly change the color property categoryItem in the categoryDelegate.
Example
Component {
id: categoryDelegate
Column {
...
Rectangle {
id: categoryItem
...
color: "blue"
...
}
}
}
EDIT:
In that case the the overall concept is wrong. In the comment of the original code the author has written A ListElement can't contain child elements, but it can contain a list of elements. So we can't highlight the child item. But the following approach will give good result to you.
import QtQuick 2.0
Rectangle {
width: 360
height: 360
ListModel {
id: model1
ListElement {
name: "name"
}
ListElement {
name: "name"
}
ListElement {
name: "name"
}
}
ListModel {
id: model2
ListElement {
name: "inside"
}
ListElement {
name: "inside"
}
ListElement {
name: "inside"
}
}
ListView {
id: outer
model: model1
delegate: listdelegate
anchors.fill: parent
}
Component {
id: listdelegate
Item {
width: 100
height: col.childrenRect.height
Column {
id: col
anchors.left: parent.left
anchors.right: parent.right
Text {
id: t1
text: name
}
ListView {
id: insidelist
model: model2
property int collapseHeightFlag: childrenRect.height
delegate: Component {
id: delegate2
Item {
width: 100
height: col2.childrenRect.height
Column {
id: col2
anchors.left: parent.left
anchors.right: parent.right
Text {
id: name1
text: name
}
}
MouseArea {
anchors.fill: parent
onClicked: {
insidelist.currentIndex = index;
}
}
}
}
contentHeight: contentItem.childrenRect.height
height: 0
anchors.left: parent.left
anchors.right: parent.right
clip: true
highlight: Rectangle {
color: "pink"
radius: 2
}
focus: true
}
}
Rectangle {
color: "red"
width: 10
height: 10
anchors.right: parent.right
anchors.rightMargin: 5
anchors.top: parent.top
anchors.topMargin: 5
MouseArea {
anchors.fill: parent
onClicked: {
if(insidelist.height === insidelist.collapseHeightFlag) {
insidelist.height = 0;
}
else
insidelist.height = insidelist.collapseHeightFlag;
}
}
}
}
}
}

Is there easy way to duplicate a RowLayout in QtQuick?

In my ui.qml I have:
RowLayout {
id: rowLayout2
x: 0
y: 397
width: 640
height: 50
clip: false
Text {
id: text4
width: 105
height: 32
text: qsTr("房间类型")
font.pixelSize: 17
wrapMode: Text.WordWrap
}
ComboBox {
id: comboBox1
activeFocusOnPress: false
model: ListModel {
id: cbItems
ListElement { text: "标准间"; color: "Yellow" }
ListElement { text: "三人间"; color: "Green" }
ListElement { text: "大床房"; color: "Brown" }
ListElement { text: "豪华套房"; color: "Blue" }
}
}
}
And I want to make a button that when clicked on duplicates this RowLayout below the original one, how do I do that?
Put it inside a Repeater and increment the model count when the button is clicked.
Button {
onClicked: {
repeater.model += 1;
}
}
...
Column {
Repeater {
model: 1
// Your rowLayout2 code
}
}

Is there a IconMode for a listview in qml?

can someone say me how to set up a icon mode for my listViewe in qml?
like this:
I know that this mode is available in the c++ version of the listview (setListMode)but in qml?
Greetings
I don't think there is a default component for this in QML but you can easily do one yourself using the Gridview Component and creating the delegate yourself.
ListModel {
id: modelIcons
ListElement { iconSource: "icon1.jpg"; iconText: "Train1" }
ListElement { iconSource: "icon2.jpg"; iconText: "Train2" }
ListElement { iconSource: "icon3.jpg"; iconText: "Train3" }
ListElement { iconSource: "icon4.jpg"; iconText: "Train4" }
ListElement { iconSource: "icon5.jpg"; iconText: "Train5" }
ListElement { iconSource: "icon6.jpg"; iconText: "Train6" }
ListElement { iconSource: "icon7.jpg"; iconText: "Train7" }
}
Component {
id: delegateListElement
Item {
width: 80
height: width
Column {
Image {
height: 50
width: 50
source: iconSource
}
Text {
text: iconText
}
}
}
}
GridView {
anchors.fill: parent
model: modelIcons
delegate: delegateListElement
focus: true
}

Resources