summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativeworkerscript.cpp
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-03-05 01:15:40 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-03-05 01:15:40 (GMT)
commit1cdaca2823a7c09f377ab205e6424e35febcbf2c (patch)
tree559c1f8c8ea2109945580fe118a6aa213c1eb349 /src/declarative/qml/qdeclarativeworkerscript.cpp
parent8a026d93a76a61415b4d697991cdd8aee6b76cb9 (diff)
parent5048b96a14b61329257e153f2551b6fca4519f84 (diff)
downloadQt-1cdaca2823a7c09f377ab205e6424e35febcbf2c.zip
Qt-1cdaca2823a7c09f377ab205e6424e35febcbf2c.tar.gz
Qt-1cdaca2823a7c09f377ab205e6424e35febcbf2c.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml: (104 commits) Include QML doc snippets in examples autotest Update QML documentation snippets to latest syntax. MouseRegion is dead. Long live MouseArea. Compile fix for wince Update QML PropertyAnimation::easing docs Add testcase for QTBUG-7730 Add autotests for tab and backtab in Keys and KeyNavigation. Run signal expressions on attached property objects in correct scope Fixup test Add support for tab and backtab in KeyNavigation Mark QGraphicsItem position properties as FINAL Move the multimedia files to the correct place. Fix grammar stringifying "on" as "readonly" Improve grouped property error messages Don't mess with highlight size if highlightFollowsCurrentItem is false. Fix ListView contentHeight calculation. Remove Qt.playSound() Add formatting functions to QML's global Qt object. Signal handler requires exactly one value. QDeclarativeContext::contextProperty() should also access ids ...
Diffstat (limited to 'src/declarative/qml/qdeclarativeworkerscript.cpp')
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp220
1 files changed, 218 insertions, 2 deletions
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index 03151e4..784353a 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -365,6 +365,8 @@ void QDeclarativeWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
workerEngine->evaluate(script);
workerEngine->popContext();
+ } else {
+ qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
}
}
@@ -382,7 +384,7 @@ QVariant QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(const QScri
quint32 length = (quint32)value.property(QLatin1String("length")).toNumber();
for (quint32 ii = 0; ii < length; ++ii) {
- QVariant v = scriptValueToVariant(ii);
+ QVariant v = scriptValueToVariant(value.property(ii));
list << v;
}
@@ -561,6 +563,65 @@ void QDeclarativeWorkerScriptEngine::run()
delete d->workerEngine; d->workerEngine = 0;
}
+
+/*!
+ \qmlclass WorkerScript QDeclarativeWorkerScript
+ \brief The WorkerScript element enables the use of threads in QML.
+
+ Use WorkerScript to run operations in a new thread.
+ This is useful for running operations in the background so
+ that the main GUI thread is not blocked.
+
+ Messages can be passed between the new thread and the parent thread
+ using sendMessage() and the onMessage() handler.
+
+ Here is an example:
+
+ \qml
+ import Qt 4.6
+
+ Rectangle {
+ width: 300
+ height: 300
+
+ Text {
+ id: myText
+ text: 'Click anywhere'
+ }
+
+ WorkerScript {
+ id: myWorker
+ source: "script.js"
+
+ onMessage: {
+ myText.text = messageObject.reply
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: myWorker.sendMessage( {'x': mouse.x, 'y': mouse.y} );
+ }
+ }
+ \endqml
+
+ The above worker script specifies a javascript file, "script.js", that handles
+ the operations to be performed in the new thread:
+
+ \qml
+ WorkerScript.onMessage = function(message) {
+ // ... long-running operations and calculations are done here
+ WorkerScript.sendMessage( {'reply': 'Mouse is at ' + message.x + ',' + message.y} );
+ }
+ \endqml
+
+ When the user clicks anywhere within the rectangle, \c sendMessage() is
+ called, triggering the \tt WorkerScript.onMessage() handler in
+ \tt source.js. This in turn sends a reply message that is then received
+ by the \tt onMessage() handler of \tt myWorker.
+
+ \sa WorkerListModel
+*/
QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent)
: QObject(parent), m_engine(0), m_scriptId(-1)
{
@@ -571,6 +632,12 @@ QDeclarativeWorkerScript::~QDeclarativeWorkerScript()
if (m_scriptId != -1) m_engine->removeWorkerScript(m_scriptId);
}
+/*!
+ \qmlproperty url WorkerScript::source
+
+ This holds the url of the javascript file that implements the
+ \tt WorkerScript.onMessage() handler for threaded operations.
+*/
QUrl QDeclarativeWorkerScript::source() const
{
return m_source;
@@ -589,6 +656,13 @@ void QDeclarativeWorkerScript::setSource(const QUrl &source)
emit sourceChanged();
}
+/*
+ \qmlmethod WorkerScript::sendMessage(jsobject message)
+
+ Sends the given \a message to a worker script handler in another
+ thread. The other worker script handler can receive this message
+ through the onMessage() handler.
+*/
void QDeclarativeWorkerScript::sendMessage(const QScriptValue &message)
{
if (!m_engine) {
@@ -616,6 +690,13 @@ void QDeclarativeWorkerScript::componentComplete()
}
}
+/*!
+ \qmlsignal WorkerScript::onMessage(jsobject msg)
+
+ This handler is called when a message \a msg is received from a worker
+ script in another thread through a call to sendMessage().
+*/
+
bool QDeclarativeWorkerScript::event(QEvent *event)
{
if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
@@ -841,6 +922,41 @@ bool QDeclarativeWorkerListModelAgent::event(QEvent *e)
return QObject::event(e);
}
+/*!
+ \qmlclass WorkerListModel QDeclarativeWorkerListModel
+ \brief The WorkerListModel element provides a threaded list model.
+
+ Use WorkerListModel together with WorkerScript to define a list model
+ that is controlled by a separate thread. This is useful if list modification
+ operations are synchronous and take some time: using WorkerListModel
+ moves these operations to a different thread and avoids blocking of the
+ main GUI thread.
+
+ The thread that creates the WorkerListModel can modify the model for any
+ initial set-up requirements. However, once the model has been modified by
+ the associated WorkerScript, the model can only be modified by that worker
+ script and becomes read-only to all other threads.
+
+ Here is an example application that uses WorkerScript to append the
+ current time to a WorkerListModel:
+
+ \snippet examples/declarative/workerlistmodel/timedisplay.qml 0
+
+ The included file, \tt dataloader.js, looks like this:
+
+ \snippet examples/declarative/workerlistmodel/dataloader.js 0
+
+ The application's \tt Timer object periodically sends a message to the
+ worker script by calling \tt WorkerScript::sendMessage(). When this message
+ is received, \tt WorkerScript.onMessage() is invoked in
+ \tt dataloader.js, which appends the current time to the worker list
+ model.
+
+ Note that unlike ListModel, WorkerListModel does not have \tt move() and
+ \tt setProperty() methods.
+
+ \sa WorkerScript, ListModel
+*/
QDeclarativeWorkerListModel::QDeclarativeWorkerListModel(QObject *parent)
: QListModelInterface(parent), m_agent(0)
{
@@ -854,6 +970,14 @@ QDeclarativeWorkerListModel::~QDeclarativeWorkerListModel()
}
}
+/*!
+ \qmlmethod WorkerListModel::clear()
+
+ Deletes all content from the model. The properties are cleared such that
+ different properties may be set on subsequent additions.
+
+ \sa append() remove()
+*/
void QDeclarativeWorkerListModel::clear()
{
if (m_agent) {
@@ -869,6 +993,13 @@ void QDeclarativeWorkerListModel::clear()
}
}
+/*!
+ \qmlmethod WorkerListModel::remove(int index)
+
+ Deletes the content at \a index from the model.
+
+ \sa clear()
+*/
void QDeclarativeWorkerListModel::remove(int index)
{
if (m_agent) {
@@ -884,6 +1015,18 @@ void QDeclarativeWorkerListModel::remove(int index)
emit countChanged();
}
+/*!
+ \qmlmethod WorkerListModel::append(jsobject dict)
+
+ Adds a new item to the end of the list model, with the
+ values in \a dict.
+
+ \code
+ FruitModel.append({"cost": 5.95, "name":"Pizza"})
+ \endcode
+
+ \sa set() remove()
+*/
void QDeclarativeWorkerListModel::append(const QScriptValue &value)
{
if (m_agent) {
@@ -914,6 +1057,21 @@ void QDeclarativeWorkerListModel::append(const QScriptValue &value)
emit countChanged();
}
+/*!
+ \qmlmethod WorkerListModel::insert(int index, jsobject dict)
+
+ Adds a new item to the list model at position \a index, with the
+ values in \a dict.
+
+ \code
+ FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
+ \endcode
+
+ The \a index must be to an existing item in the list, or one past
+ the end of the list (equivalent to append).
+
+ \sa set() append()
+*/
void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value)
{
if (m_agent) {
@@ -946,6 +1104,30 @@ void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value)
emit countChanged();
}
+/*!
+ \qmlmethod object ListModel::get(int index)
+
+ Returns the item at \a index in the list model.
+
+ \code
+ FruitModel.append({"cost": 5.95, "name":"Jackfruit"})
+ FruitModel.get(0).cost
+ \endcode
+
+ The \a index must be an element in the list.
+
+ Note that properties of the returned object that are themselves objects
+ will also be models, and this get() method is used to access elements:
+
+ \code
+ FruitModel.append(..., "attributes":
+ [{"name":"spikes","value":"7mm"},
+ {"name":"color","value":"green"}]);
+ FruitModel.get(0).attributes.get(1).value; // == "green"
+ \endcode
+
+ \sa append()
+*/
QScriptValue QDeclarativeWorkerListModel::get(int index) const
{
QDeclarativeEngine *engine = qmlEngine(this);
@@ -962,6 +1144,21 @@ QScriptValue QDeclarativeWorkerListModel::get(int index) const
return rv;
}
+/*!
+ \qmlmethod WorkerListModel::set(int index, jsobject dict)
+
+ Changes the item at \a index in the list model with the
+ values in \a dict. Properties not appearing in \a valuemap
+ are left unchanged.
+
+ \code
+ FruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
+ \endcode
+
+ The \a index must be an element in the list.
+
+ \sa append()
+*/
void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value)
{
if (m_agent) {
@@ -995,6 +1192,22 @@ void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value)
}
}
+/*!
+ \qmlmethod WorkerListModel::sync()
+
+ Writes any unsaved changes to the list model. This must be called after
+ changes have been made to the list model in the worker script.
+
+ Note that this method can only be called from the associated worker script.
+*/
+void QDeclarativeWorkerListModel::sync()
+{
+ // This is really a dummy method to make it look like sync() exists in
+ // WorkerListModel (and not QDeclarativeWorkerListModelAgent) and to let
+ // us document sync().
+ qmlInfo(this) << "sync() can only be called from a WorkerScript";
+}
+
QDeclarativeWorkerListModelAgent *QDeclarativeWorkerListModel::agent()
{
if (!m_agent)
@@ -1013,6 +1226,10 @@ QString QDeclarativeWorkerListModel::toString(int role) const
return m_roles.value(role);
}
+/*!
+ \qmlproperty int ListModel::count
+ The number of data entries in the model.
+*/
int QDeclarativeWorkerListModel::count() const
{
return m_values.count();
@@ -1038,4 +1255,3 @@ QT_END_NAMESPACE
#include "qdeclarativeworkerscript.moc"
-