November 15, 2010

axeljaeger axeljaeger
Ant Farmer
3 posts

How to bind TextInput.text to QString property in two ways?

 

Hello,
I try to bind a QML TextInput to a QString-property of a C++-QObject. My expectation is that the text in the TextInput is updated whenever the NOTIFY-signal of that property is fired AND that the setter of that property is called whenever the text in the TextInput is changed by the user. However, I can only see the first behaviour. I created a small example that has a QLineEdit and a QDeclarativeView in a layout. The lineEdit is exposed to the QML-file using a context property. Now I bind to the property using this QML-file:

  1. import Qt 4.7
  2. Rectangle {
  3.     width: 240
  4.     height: 320
  5.  
  6.     TextInput {
  7.         text: lineEdit.text
  8.         anchors.fill: parent
  9.     }
  10. }

Whenever I change the text in the QLineEdit now, the TextInput within the declarative view is updated. However, when I change the test in the TextInput, nothing happens. I expected that the QLineEdit would be updated as well. Is this intended behavior? If yes, how to keep both in sync? Shouldn’t a declarative binding work in two ways?

13 replies

November 15, 2010

Deleted Member # 4a2 Deleted Member # 4a2
Ant Farmer
1481 posts

take a look at this example on forum nokia: http://wiki.forum.nokia.com/index.php/CS001625_-_Connecting_Qt_signal_to_QML_function [wiki.forum.nokia.com]

November 15, 2010

axeljaeger axeljaeger
Ant Farmer
3 posts

Thank you but this does not help because it is just an alternate way to do the part that already works. I want the C++ lineedit to be updated from the QML one. And I actually want to do it in a declarative way and not an imperative way.

November 16, 2010

mbrasser mbrasser
Lab Rat
452 posts

Hi,

QML currently only supports “one-way” bindings. You can use the Binding [doc.qt.nokia.com] element if you want to bind lineEdit.text to the text of the TextInput as well.

  1. import Qt 4.7
  2. Rectangle {
  3.     width: 240
  4.     height: 320
  5.  
  6.     TextInput {
  7.         id: input
  8.         text: lineEdit.text
  9.         anchors.fill: parent
  10.     }
  11.     Binding {
  12.         target: lineEdit
  13.         property: "text"
  14.         value: input.text
  15.     }
  16. }

Regards,
Michael

November 16, 2010

axeljaeger axeljaeger
Ant Farmer
3 posts

Thank you. This is exactly the information I was looking for.

May 10, 2011

njeisecke njeisecke
Lab Rat
50 posts

Hi,

Doing this will generate a console warning:

QML TextInput: Binding loop detected for property “text”

It works nevertheless but I don’t like warnings.

Any ideas?

Regards

Nils

May 10, 2011

Andre Andre
Robot Herder
6399 posts

File a bugreport :-)

May 10, 2011

njeisecke njeisecke
Lab Rat
50 posts

Well, it actually is a binding loop. However it does not do any harm as long as the setter on the C++ side is implemented correctly.

May 10, 2011

Andre Andre
Robot Herder
6399 posts

I meant it more as: file a bug report with a suggestion to make two way bindings possible :-)

May 11, 2011

mbrasser mbrasser
Lab Rat
452 posts

njeisecke wrote:
Hi,

Doing this will generate a console warning:

QML TextInput: Binding loop detected for property “text”

It works nevertheless but I don’t like warnings.

Any ideas?

Hi Nils,

Is it the exact snippet above (with a QLineEdit in C++) you are testing or something else?

Typically this warning is avoided via the C++ implementation of the setter, e.g. setText() will be implemented to only emit the NOTIFY signal if the property actually changes. I thought in this case both TextInput and QLineEdit would have done this, though (so there might be something else at play here that I’ve missed).

Regards,
Michael

May 11, 2011

Andre Andre
Robot Herder
6399 posts

Are you suggesting that Qt Quick is at runtime able to analyze if the (C++) objects block emitting a changed signal if you set the same value on a property? And that they only should give the Binding Loop warning if they don’t block the signal? That would be pretty cool! But I think that is unlikely. I think it is a warning because it can not be detected if the signal is emitted. If it could, it would (should) be an error instead.

May 12, 2011

njeisecke njeisecke
Lab Rat
50 posts

Hi Michael,

my setter was on the c++ side and indeed wrongly implemented (stupid me).

With an implementation like this everything works as expected:

  1. void MyObject::setValue(const QString &value)
  2. {
  3.   // this avoids the (absolutely correct) warning
  4.   if (m_value == value)
  5.     return;
  6.  
  7.   m_value = value;
  8.   emit valueChanged():
  9. }

So actually there seems to be some runtime analysis. Cool ;-)

May 12, 2011

Andre Andre
Robot Herder
6399 posts

Does implementing it like this fix the warning? That would be awesome!
If so, then perhaps the warning should be an error instead?

May 12, 2011

njeisecke njeisecke
Lab Rat
50 posts

Yes it does, I’ve just commented out the check and the warning appears.

 
  ‹‹ regarding multimedia file qmlmultimediaplugin      Displaying all images from the same folder? ››

You must log in to post a reply. Not a member yet? Register here!