PDA

View Full Version : ActiveFocus with TextEdit



volcano
21st June 2016, 07:18
Hi All,

I have an application which uses QML Treeview. The items of the treeview needs to be editable, hence I have configured a delegate which toggles between text and textedit when user sets a flag.

Here's the code


ApplicationWindow {
id:window
visible: true
width: 640
height: 480
title: qsTr("File System")

property var clickedIndex: -1

ListModel{
id:listModel
ListElement{
colorName:"red"
}
ListElement{
colorName:"yellow"
}
ListElement{
colorName:"pink"
}
}

ListView{
id:listview
height: parent.height
width: 50
model: listModel
anchors.left: parent.left

delegate: Component{
Rectangle{
color: colorName
height: 50
width: 50
MouseArea{
anchors.fill: parent
onClicked: {
console.log("Clicked " + colorName)
forceActiveFocus()
}
}
}
}
}

TreeView {
id: view
objectName: "view"
anchors.margins: 2 * 12
anchors.left:listview.right
anchors.top:listview.top
anchors.right:parent.right
anchors.bottom:parent.bottom

model: treemodel
selectionMode:SelectionMode.ExtendedSelection
headerVisible: true

TableViewColumn {
title: "Name"
role: "Title"
width: 300
delegate: Component{
Item {
Text {
id: test
text: model.Title
color: model.IsSelected ? "green" : "blue"
width: parent.width
visible: !model.EditEnabled
}
TextEdit{
id: textField
width: parent.width
visible: model.EditEnabled

onVisibleChanged: {
if(visible)
{
textField.text = model.Title
forceActiveFocus()
}

onActiveFocusChanged: {
if(!activeFocus)
{
model.EditEnabled = activeFocus
}
}

onTextChanged: {
model.Title = textField.text
}
}
}
}
}
}

TableViewColumn {
title: rect
role:"IsSelected"
width: 25

delegate: Component{
Rectangle{
id: rect
anchors.right: test.right
color: model.IsSelected ? "red" : "teal"
MouseArea{
anchors.fill: parent
onClicked: {
model.EditEnabled = true;
}
}
}
}
}
}
}


However, I want the textEdit to loose focus when i click any other item displayed in the screen.

Please provide me some pointers

anda_skoa
21st June 2016, 09:51
One thing you could try is to bind the "enabled" property to the "visible" property, so when it becomes non-visible it would also be disabled.

Another option would be to switch the delegate depending on whether the item is editable or not.

Cheers,
_

volcano
21st June 2016, 11:52
Thanks for the inputs anda_skoa

The problem I'm facing is that I have so many items in the QML page.
The treeview has editable item delegate, when I click on any other item i want the activefocus of the textedit to be lost.

Could you show me how to bind the enabled to visible? I keep getting the binding loop warning for visible property

Is it possible to do so without setting activeFocus to the other clicked item.

anda_skoa
21st June 2016, 13:16
enabled: visible


If that doesn't work, use two components and switch between them.

Cheers,
_

volcano
21st June 2016, 17:20
Thanks for the suggestion anda_skoa.

I understand that the solution suggested would work for items in the treeview.

However, the application has a treeview and listview of items.

The treeview has an editable delegate. So when I'm editing an item on the treeview and click an item in the listview, I would like the item which is in edit mode to loose focus.

The way expressed in the example is setting activeFocus to the listview item. Is there another way to do so without activeFocus?

anda_skoa
21st June 2016, 18:32
So you don't want to deactivate editing only remove the focus?
Because in your original code removing the focus would also deactivate editing.

If you want to keep the editable delegate but remove its focus, then I don't understand what the problem is that you are asking for help with.
Does setting the focus to another component not work?

Cheers,
_

volcano
22nd June 2016, 07:21
The treeview has an editable delegate. So when I'm editing an item on the treeview and click an item in the listview, I would like the item which is in edit mode to loose focus.

I meant I would like to change the edit mode to non-edit mode, if a user clicks on any other item on the qml page.

Let me explain the scenario, I have buttons, a treeview and listview in the same screen. When I enable the item to be edited and start editing the item in the treeview by setting activeFocus, so that the keyboard key strokes are accepted by the textedit.

Now if I click on some other button on the screen or any item in the listview without setting the activeFocus on the item I just clicked, the activeFocus of the item in the treeview isn't lost, this activeFocus loss is used to set the text and change the edit mode to non-edit mode.

So currently i'm setting activeFocus explicitly on the item I clicked(i.e. button or item in the listview) other than the treeview item to disable the activeFocus on the treeview item.

Is there a better way to shift activeFocus from the treeview item rather than configuring activeFocus on any other item which is clicked?

anda_skoa
22nd June 2016, 14:39
I think I understand better now.

- when click a button or a ListView entry, you want to stop editing mode on the tree view
- you currently do that by tracking activeFocus in the tree view delegate

What about this
- add a method to your tree model that resets all "edit enabled" values
- call that method when you want to stop editing
- ignore anything focus related in QML

I.e. instead of calling forceActiveFocus() in the list view delegate's mouse area you would then do something like


treemodel.stopEditing()


Cheers,
_

volcano
24th June 2016, 08:08
Thanks anda_skoa for the suggestions..

But then for every new item added I have to ensure that the method is called.

Can you suggest if there exist another way to do so?

anda_skoa
24th June 2016, 10:43
Difficult.

What you could try is a MouseArea that fills the whole window, sits below the tree view but above everything else.
When it is clicked, it calls the reset method.
It would also need to set propagateComposedEvents otherwise you can't click on anything below it.

Cheers,
_

volcano
28th June 2016, 04:16
Thanks anda_skoa.

Will try out your suggestion.