Kent
Qt
QSA
Posted by Kent
 in Qt, QSA
 on Friday, August 29, 2008 @ 14:04

Been having some fun this week trying to add support for data bindings to Qt Script, and now I have something that seems to work. This code shows the basic usage:

QScriptEngine engine;
QPushButton button;
QScriptValue scriptButton = engine.newQObject(&button);
engine.evaluate("x = 'foo'");
scriptButton.setProperty("text", "x", QScriptValue::DataBinding);

This will cause the button’s text property to be updated whenever the script variable x changes, either from C++ (QScriptValue::setProperty()) or from
script. QObject properties can be part of the binding expression as well, as long as the NOTIFY attribute is specified in the Q_PROPERTY definition. Qt Script will discover that the property has a signal associated with it and use it to track changes. Qt’s classes already use NOTIFY for some properties (e.g. QLabel::text).

Below is a small example. The text property of a label is bound to the text property of a lineedit and the script variable verb; the final value is made by concatenating the lineedit’s text, the verb and a string literal.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget win;
    QVBoxLayout *vbox = new QVBoxLayout(&win);
    QLineEdit *lineEdit = new QLineEdit();
    QLabel *label = new QLabel();
    label->setStyleSheet("font-size: 24px");
    vbox->addWidget(lineEdit);
    vbox->addWidget(label);

    QScriptEngine engine;
    QScriptEngineDebugger debugger;
    debugger.attachTo(&engine);
    vbox->addWidget(debugger.widget(QScriptEngineDebugger::ConsoleWidget));

    QScriptValue scriptLineEdit = engine.newQObject(lineEdit);
    engine.globalObject().setProperty("lineEdit", scriptLineEdit);
    QScriptValue scriptLabel = engine.newQObject(label);
    engine.globalObject().setProperty("label", scriptLabel);

    engine.evaluate("verb = 'smack'");
    scriptLabel.setProperty("text", "lineEdit.text + ' ' + verb + 's you!'", QScriptValue::DataBinding);

    win.show();

    return app.exec();
}

The result, after typing something into the lineedit and assigning something to verb:

Qt Script data binding example

I’ve also added an extension to QScriptClass that enables you to send property change notifications for custom (non-QObject-based) script objects, i.e. you can use your own notify mechanism.

As I said, this isn’t in Qt yet, it’s just an experiment, but it’s looking pretty interesting.

10 Responses to “Data Bindings”

» Posted by Ian Monroe
 on Friday, August 29, 2008 @ 15:46

Thats pretty mind-blowing. Is there some language construct your emulating here?

I see how its useful, I’m just not sure where you’d get the idea to do something like this. :)

» Posted by shamaz
 on Friday, August 29, 2008 @ 16:48

Makes me think of https://beansbinding.dev.java.net/
You might find inspiration there :)

» Posted by JarJarThomas
 on Friday, August 29, 2008 @ 17:52

sounds usefull but i would like to have the same in c++.
Connecting properties directly to widgets without the need to write for each small dialog x set/get widget functions

» Posted by Ian Monroe
 on Friday, August 29, 2008 @ 18:05

JarJar, where do you think these properties come from? They’re defined by set/getters.

In the example Kent could’ve done lineEdit.text = “love” instead and it would’ve worked. I guess its a small example. But I don’t get the point…

» Posted by Ian Monroe
 on Friday, August 29, 2008 @ 18:08

Ah I guess not, I misread. I’ll go back to seeing how it could be useful but wondering why you’d do it this way. :)

» Reply from Kent
 on Friday, August 29, 2008 @ 18:12
Kent

JarJarThomas: Yep, you will be able to that, similar to how there’s qScriptConnect() in C++. There will be a function like this:

QScriptEngine::bindProperty(QObject* object, QString name, QString expression)

» Reply from Kent
 on Friday, August 29, 2008 @ 18:16
Kent

Ian: I didn’t get the idea. There’s JavaFX and WPF, for example.

» Posted by Axel
 on Sunday, August 31, 2008 @ 08:26

Can you tell me more about the NOTIFY-keyword of Q_PROPERTY? It looks like something I wanted in Qt for years and that I finally submitted as feature request: http://trolltech.com/developer/task-tracker/index_html?method=entry&id=217531

I dont see any documentation for it neither in the documentation of Q_OBJECT nor QMetaProperty. If it is a new feature that is about to be added in Qt 4.5, please make sure that you can query for the signal in QMetaProperty. Then you could add two text labels to a form, bind them to x and y of the form and show them the position of the form while moving in preview mode. Very cool.

» Reply from Kent
 on Monday, September 01, 2008 @ 12:57
Kent

Axel: Yes, this is what you’re looking for: http://doc.trolltech.com/main-snapshot/qmetaproperty.html#notifySignal
Unfortunately the docs haven’t been updated yet.
If you use NOTIFY in the property definition (e.g. “NOTIFY textChanged”), QMetaProperty::notifySignal() will return a QMetaMethod that describes the notify signal (i.e. so you can connect to it).

» Posted by Axel
 on Monday, September 15, 2008 @ 10:17

How will the change of dynamic properties be tracked? Will there be a signal for this? Will the Qt api be updated to have change signals for every property?



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.