PDA

View Full Version : QML Controls Feedback Problem



jakob.braun@posteo.de
16th February 2016, 13:06
Hey,
I have a problem with QML Controls:
I try to connect two TextAreas via Network:

TextArea{
id: textarea
onTextChanged: {
//send message
}
}
//onMessage:
textarea.text = message;


The Problem is that
onTextChanged is although triggered if the text is set by a message. By that, a new Message is generated, which causes the generation of an other Massage on the other side an so on...

My approach was to add a property to detect, the event was triggered manually but it won't work:

TextArea{
property bool surpress: false
function setPassive(newText){
surpress = true;
text = newText;
}
id: textarea
onTextChanged: {
if(surpress){
surpress = false;
return;
}
//send message
}
}
//onMessage:
textarea.setPassive(message);



Any Ideas?

best regards,
Jakob

anda_skoa
16th February 2016, 13:30
Are you sure you want to send the full string on every change?

Wouldn't it make more sense to have something like a "send" button?

Cheers,
_

jakob.braun@posteo.de
16th February 2016, 13:34
Hey,
Thanks for your quick replay.
Yes, I'm sure, as this TextArea is only the simplest Example. I although have the problem for example with slider.
There I control by back-end in real-time with multiple synced clients.
Best Regards,
Jakob

anda_skoa
16th February 2016, 14:58
Hmm, ok.

Your approach works for me:


import QtQuick 2.4
import QtQuick.Controls 1.2

Column {
TextArea {
id: text1

property bool ignoreNextTextChange: false

function setTextGuarded(value) {
ignoreNextTextChange = true;
text = value;
}

onTextChanged: {
if (ignoreNextTextChange) {
ignoreNextTextChange = false;
return;
}

console.log("textChanged: " + text);
}
}

TextInput {
text: "enter text here..."
onEditingFinished: text1.setTextGuarded(text);
}
}

jakob.braun@posteo.de
16th February 2016, 17:47
OK in this case it works: Here my code:


import QtQuick 2.3
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

ColumnLayout{

TextArea{
id:texta1
text:"text1";
onTextChanged: {
console.log("text1 changed");
texta2.text = text;
}
}

TextArea{
id:texta2;

onTextChanged:{
console.log("text2 changed");
texta1.text = text;
}
}

}
}

When I do a change in a first text box, I get the following output:

text1 changed
text2 changed
That's perfect. There is no recursion.

I figured out why this works:
We change texta1 --> it calls texta1.onTextChanged --> texta2.text is set to texta1.text --> texta2 text changed --> texta2.onTextChanged is called --> texta1.text is set to texta2.text --> texta1.text has not changed --> no Handler is called

The problem in my case is, that the two boxes are connected via network. So when I type "ab" int the TextArea of client 1, I takes some Time, until the value ("a") is send to client to Client 2 and Client 2 sends it back to Client 1.
But Client 1s text is already "ab", as in the main time I have typed the b. So the software begins to swing between the two values.

In order to solve this problem and avoid this overhead feedback from client 2, I need an option to set the value of the TextArea without triggering the signal or an option to detect this feedback an block it (see my first example).

Best regards and thanks for the ideas,
Jakob