Writing QML Application in a Flux way
-
QuickFlux v1.0.1 has been released.
Changes:
AppListener
Added new properties, “filter” and “filters”. Once it is set, only message with name matched will emit “dispatched” signal.
By using “filter" property, users could write their listener in a more simple way:
New Method:
AppListener { filter: “NewItem" onDispatched: { // Code to handle “NewItem” message here. } }
Old method:
// Listen for multiple messages. AppListener { onDispatched: { switch (name) { case "messageType1": // ... break; case "messageType2": // ... break; } } }
`
orAppListener { Component.onComponented: { on("messageType1",function() { /// Your code here. }); on("messageType2",function() { /// Your code here. }); } }
-
thanks for posting this.
in the qmlunittests main.cpp references
#include <QtQuickTest/quicktest.h>but i can't find it in the https://github.com/benlau/quickflux project.
do you have an example app ? -
@clogwog The qmlunittests program is an test suite to verify the correctness of the program. Things like header of "<QtQuickTest/quicktest.h>" is not needed in your program. So you may just ignore this folder.
Instead, I just made an example program to demonstrate how to use it:
quickflux/examples/todo at master · benlau/quickflux
Please feel free to ask if you have any questions.
-
Great article. Thanks. This will help me a lot.
-
v1.0.3 has been released.
Changes:
New Components
- AppScript
AppScript is a helper component to handle asynchronous sequential workflow. The immediate benefit of using AppScript is the centralisation of code in a place. Instead of placing them within onXXXX code block in several components in several places.
- AppListenerGroup
AppListenerGroup collects listener ID from all of its child AppListener and initialize their waitFor property.
It could be used as the base type of a Store component for setup dependence between them.MyStore1.qml
AppListenerGroup { AppListener { } AppListener { } }
MyStore2.qml
AppListenerGroup { waitFor: MyStore1.listenerIds }
Changes
AppDispatcher
- Added addListener() function
Registers a callback to be invoked with every dispatched message. Returns a listener ID that can be used with waitFor().
- Added removeListener() function
Remove a callback by the listenerId returned by addListener
- Added waitFor() function
Waits for the callbacks specified to be invoked before continuing execution of the current callback. This method should only be used by a callback in response to a dispatched message.
AppListener
- Added “listenerId” property
The listener ID of this component. It could be used with AppListener.waitFor/AppDispatcher.waitFor to control the order of message delivery.
- Added “waitFor” property
If it is set, it will block the emission of dispatched signal until all the specified listeners invoked.
Example code:
AppListener { id: listener1 } AppListener { id: listener2 waitFor: [listener1.listenerId] }
-
Hi Ben,
Thank for your contributions!
Did you discuss about writing QML Application in a Flux way with developers of Qt via Qt development mailing list?
If not, why not?
Merry Christmas!
-
@Vincent007 no. hmmm... Just I can't think of any reason to send to dev mailing list. Ask them for comment? or ask them to include related class in next version? Ofcoz it will be better if more people can comment / raise suggestion, but I just not sure should I send to dev mailing list.
Merry Christmas!
-
Hi Ben,
I think your work can help Qt developers think how QML should be evolved in feature. Therefore you can discuss with them about the evolution of QML by your work.
-
@Vincent007 hmm. Let's me think about it. By the way, I am going to publish another article with similar topic but better explanation, code and diagram on a blog in this week.
-
Hi Ben,
i'm not sure if this is a bug but i'm trying to figure out how to use quickflux by making a small change to the todo example.
I added a 'mark all items done' button and mark all items as done. however the ui doesn't always update.
example: 1) start application (3 items in list 1 in done)
2) press 'all done' -> all items disappear (expected)
3) show all items by checking 'show completed' (expecteD)
4) unmark one item (for example 'Task A')
5) press 'all done' -> 'Task A' doesn't update to done ?if i uncheck and re-check 'show completed' the model and view are back in sync.
https://github.com/clogwog/fluxtest1
am i missing something ?
-
@clogwog I can't reproduce your problem in my example program and in your code. When it is set to "Show Completed". It will show every tasks. So if you set a task done in "Show Completed" mode. It won't disappear. The behaviour should be correct.
-
no, i was expecting it to show all tasks as you said, i just expected it to switch back to checked when i pressed the 'all done' button
so when you are in the 'show completed' mode in step 5 with a task you just set to 'uncompleted' and then press 'all done' your tasks goes back to checked ?
-
@clogwog said:
no, i was expecting it to show all tasks as you said, i just expected it to switch back to checked when i pressed the 'all done' button
so when you are in the 'show completed' mode in step 5 with a task you just set to 'uncompleted' and then press 'all done' your tasks goes back to checked ?
oh, you mean in your program. I didn't realize that you have added a "All Done" button. The problem is about data binding in Qt. Qt use one-way data binding. Although it has binded CheckBox.checked to model.done , the binding will lost whatever it is toggled by user event. It is overridden by system. And that is why step 5 failed.
You may solve this problem in this way:
At TodoVisualDataModel.qml:
delegate: TodoItem { id:item uid: model.uid title: model.title property bool done: model.done onDoneChanged: { checked = model.done; } Component.onCompleted: { item.VisualDataModel.inNonCompleted = Qt.binding(function() { return !model.done}) } }
@benevo: thx. The article is not ready yet. I will post it within this few days.
-
nice,thanks for share,i think MVC is too good for our Qml project.
-
@benevo @Vincent007 The new article is ready.