[SailfishDevel] QDeclarativePropertyMap not dynamic?
christopher.lamb at thurweb.ch
christopher.lamb at thurweb.ch
Sat Jun 15 09:44:22 UTC 2013
Hi Superpelican
I had almost forgotten PropertyChanged!
It was a nonsense example to show 4 different ways of doing the same
thing, to prove / disprove that all 4 options work.
In a real life application that actually does something useful you
would only use one of the 4 options to respond to one change.
Comment things in and out, and you will see that all 4 approaches are
independent.
What I was trying to show is that you can respond to a change in a
property (both QML native, and one imported from C++) by either direct
binding, or in response to an onXxxxChanged signal / event handler.
Whether you use a binding, or an onXxxxChanged signal is a matter of
taste and horses for courses.
If your changes are simple and few in number, then binding is a good option.
If you want to change lots of things, with complex logic, then
grouping all of this together in an onXxxxChanged or even a State
might be the better option.
I vaguely remember finding cases where binding did not work as
expected, but can't remember what these were.
From a software engineering / architectural point of view it also
depends on where you wish to embed control and knowledge of other
items. Should the thing doing the change be in control
(onXxxxChanged), or the thing that changes (the binding approach)?
I can't really comment on if there are c++ alternatives to the plugin
approach. My c++ programming follows the cut and paste school. In
Harmattan and Sailfish I have successfully made several c++ plugins as
a last resort approach when I have found no clean way to achieve the
same with QML / javascript. So far Plugins have worked for me.
Zitat von Superpelican <superpelican at zoho.com>:
> Hi everyone,
>
> I've been looking at the PropertyChanged project again and do I need
> to use both the Q_PROPERTY stuff and the method/signals way? Or can
> I just use 1 of them?
>
> Also do I need to make a plugin of the C++ part of my application or
> is there also another way to do it?
>
> Kind Regards,
>
> Superpelican
>
>
> On 05/09/2013 04:30 PM, christopher.lamb at thurweb.ch wrote:
>> Hi SuperPelican
>>
>> After a little playing around, I have created a minimal SailfishOS
>> app that demonstrates interaction between a c++ plugin and
>> SailfishOS QML UI elements.
>>
>> Once again I have gone the QmlRegisterType / plugin approach. The
>> app itself is the default SailfishOS QML project, with a few minor
>> changes.
>>
>> The app has a SailfishOS PullDownMenu. If you click on the MenuItem
>> "increment counters", four QML labels have their values changed,
>> each by a different approach.
>>
>> When the MenuItem is clicked, it actually updated 2 properties, one
>> QML "FirstPage.qmlCounter"; and one "cppCounter" exposed by the C++
>> plugin CPlusPlusCounter 1.0 (which is instantiated as a QML object
>> myCPlusPlusCounter.
>>
>> 1) "qml.counter binding" is a simple binding to the QML property
>> "qmlCounter" (no C++)
>> 2) "qml.counter onChanged" is changed by the "onQmlCounterChanged"
>> event of the same QML property (no C++)
>> 3) "myCPlusPlusCounter binding" is a binding to the property
>> "cppCounter" exposed by the C++ plugin
>> 4) "myCPlusPlusCounter onChanged" is changed by the
>> "onCppCounterChanged" event of the same C++ plugin property
>>
>> All the QML changes are in FirstPage.qml
>> C++ required minor changes to main.cpp ( qmlRegisterType entry + includes)
>> and the new files cpluspluscounter.h / .cpp
>>
>> You should find the entire project as an attachment to this post.
>>
>> I hope this helps
>>
>> Chris
>>
>>
>> Zitat von Superpelican <superpelican at zoho.com>:
>>
>>> I'm trying to create a hybrid QML/C++ application, where the logic
>>> is written in C++ and the interface is QML/Sailfish Silica based.
>>>
>>> I'm currently playing around with the different ways to let
>>> QML/C++ communicate with each other. I currently have this code:
>>>
>>> <code>
>>> #include <QApplication>
>>> #include <QGraphicsObject>
>>> #include <QDir>
>>> #include <QDeclarativeView>
>>> #include <QDeclarativeContext>
>>> #include <QDeclarativeEngine>
>>> #include <QDeclarativeComponent>
>>> #include <QDebug>
>>> #include <QDeclarativePropertyMap>
>>>
>>> #ifdef HAS_BOOSTER
>>> #include <MDeclarativeCache>
>>> #endif
>>>
>>> Q_DECL_EXPORT int main(int argc, char *argv[])
>>> {
>>> #ifdef HAS_BOOSTER
>>> QScopedPointer<QApplication>
>>> myapp(MDeclarativeCache::qApplication(argc, argv));
>>> #else
>>> QScopedPointer<QApplication> myapp = new QApplication(argc, argv);
>>> #endif
>>>
>>>
>>> #ifdef HAS_BOOSTER
>>> QScopedPointer<QDeclarativeView>
>>> appview(MDeclarativeCache::qDeclarativeView());
>>> #else
>>> QScopedPointer<QDeclarativeView>(new QDeclarativeView);
>>> #endif
>>>
>>> QDeclarativePropertyMap binding_map;
>>> binding_map.insert("question_txt", QVariant(QString("5 * 5 =")));
>>> binding_map.insert("color", QVariant(QString("dark red")));
>>> QScopedPointer<QDeclarativeContext>
>>> binding_context(appview->rootContext());
>>> binding_context->setContextProperty("binding_map", &binding_map);
>>> QString file = "main.qml";
>>> QString path = QString(DEPLOYMENT_PATH);
>>> appview->setSource(QUrl::fromLocalFile(path + file));
>>> appview->setResizeMode(QDeclarativeView::SizeRootObjectToView);
>>> appview->setAttribute(Qt::WA_OpaquePaintEvent);
>>> appview->setAttribute(Qt::WA_NoSystemBackground);
>>> appview->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
>>> appview->viewport()->setAttribute(Qt::WA_NoSystemBackground);
>>> appview->showFullScreen();
>>> binding_map["question_txt"] = QVariant(QString("overwritten 5 * 5 ="));
>>> return myapp->exec();
>>> }
>>> </code>
>>> I need to let C++ print text in the QML interface (the question)
>>> and C++ has to obtain the
>>> answer the user has answered in the QML interface (TextField
>>> Silica component). That's basically
>>> the needed communication between C++ and QML.
>>>
>>> So I thought that I'd create a QDeclarativePropertyMap in C++.
>>> This propertymap will contain the question.
>>> My program has a while loop that asks the user new questions each
>>> time the loop runs(the logic code can be found here
>>> <https://bitbucket.org/Superpelican/clamshell_cli>,
>>> but it hasn't been adjusted for use with a GUI, it's currently a
>>> CLI application). So I need to constantly update the QML UI from C++
>>> while the programs running, after I've setup the QDeclarativeView etc.
>>>
>>> However I noticed that if you change a value in the propertymap
>>> after initializing and showing the QDeclarativeView, the UI won't
>>> be updated!
>>> I thought the QDeclarativePropertyMap was dynamic!
>>> http://qt-project.org/doc/qt-4.8/qdeclarativepropertymap.html#details:
>>> "The binding is dynamic - whenever a key's value is updated,
>>> anything bound to that key will be updated as well."
>>>
>>> Kind Regards,
>>>
>>> Superpelican
>>>
>>>
>>>
>
>
> _______________________________________________
> SailfishOS.org Devel mailing list
>
More information about the Devel
mailing list