/PCbuild/

ject*>(); return object->metaObject()->property(1).read(object); // the first property after objectName } - return data->m_model->m_modelList->at(data->m_index); + return data->m_model->m_listAccessor->at(data->m_index); } else { // return any property of a single object instance. - QObject *object = data->m_model->m_modelList->at(0).value(); + QObject *object = data->m_model->m_listAccessor->at(0).value(); return object->property(prop.name()); } } else if (data->m_model->m_listModelInterface) { @@ -531,7 +531,7 @@ QFxVisualDataModelParts::QFxVisualDataModelParts(QFxVisualDataModel *parent) QFxVisualDataModelPrivate::QFxVisualDataModelPrivate(QmlContext *ctxt) : m_listModelInterface(0), m_abstractItemModel(0), m_visualItemModel(0), m_delegate(0) -, m_context(ctxt), m_parts(0), m_modelList(0) +, m_context(ctxt), m_parts(0), m_listAccessor(0) { } @@ -556,8 +556,8 @@ QFxVisualDataModel::QFxVisualDataModel(QmlContext *ctxt) QFxVisualDataModel::~QFxVisualDataModel() { Q_D(QFxVisualDataModel); - if (d->m_modelList) - delete d->m_modelList; + if (d->m_listAccessor) + delete d->m_listAccessor; } QVariant QFxVisualDataModel::model() const @@ -569,8 +569,8 @@ QVariant QFxVisualDataModel::model() const void QFxVisualDataModel::setModel(const QVariant &model) { Q_D(QFxVisualDataModel); - delete d->m_modelList; - d->m_modelList = 0; + delete d->m_listAccessor; + d->m_listAccessor = 0; d->m_modelVariant = model; if (d->m_listModelInterface) { // Assume caller has released all items. @@ -642,8 +642,8 @@ void QFxVisualDataModel::setModel(const QVariant &model) this, SLOT(_q_destroyingPackage(QmlPackage*))); return; } - d->m_modelList = new QmlListAccessor; - d->m_modelList->setList(model, d->m_context?d->m_context->engine():qmlEngine(this)); + d->m_listAccessor = new QmlListAccessor; + d->m_listAccessor->setList(model, d->m_context?d->m_context->engine():qmlEngine(this)); if (d->m_delegate && d->modelCount()) { emit itemsInserted(0, d->modelCount()); emit countChanged(); diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index b95d6ad..fdc57ff 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -100,6 +100,8 @@ QmlTimer::QmlTimer(QObject *parent) \qmlproperty int Timer::interval Sets the \a interval in milliseconds between triggering. + + The default interval is 1000 milliseconds. */ void QmlTimer::setInterval(int interval) { @@ -123,6 +125,8 @@ int QmlTimer::interval() const For a non-repeating timer, \a running will be set to false after the timer has been triggered. + \a running defaults to false. + \sa repeat */ bool QmlTimer::isRunning() const @@ -148,6 +152,8 @@ void QmlTimer::setRunning(bool running) specified interval; otherwise, the timer will trigger once at the specified interval and then stop (i.e. running will be set to false). + \a repeat defaults to false. + \sa running */ bool QmlTimer::isRepeating() const @@ -169,7 +175,11 @@ void QmlTimer::setRepeating(bool repeating) \qmlproperty bool Timer::triggeredOnStart If \a triggeredOnStart is true, the timer will be triggered immediately - when started, and subsequently at the specified interval. + when started, and subsequently at the specified interval. Note that for + a Timer with \e repeat set to false, this will result in the timer being + triggered twice; once on start, and again at the interval. + + \a triggeredOnStart defaults to false. \sa running */ @@ -198,7 +208,7 @@ void QmlTimer::setTriggeredOnStart(bool triggeredOnStart) void QmlTimer::start() { Q_D(QmlTimer); - d->pause.start(); + setRunning(true); } /*! @@ -211,7 +221,7 @@ void QmlTimer::start() void QmlTimer::stop() { Q_D(QmlTimer); - d->pause.stop(); + setRunning(false); } void QmlTimer::update() diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 4724278..f2ddbb7 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -7,13 +7,16 @@ SUBDIRS += datetimeformatter \ pathview \ qfxtext \ qfxtextedit \ - simplecanvasitem \ repeater \ qmllanguage \ qmlecmascript \ qmlmetaproperty \ qmllist \ qmllistaccessor \ + qmltimer \ + qfxloader \ + qfxwebview \ + states \ visual # Tests which should run in Pulse diff --git a/tests/auto/declarative/qmltimer/qmltimer.pro b/tests/auto/declarative/qmltimer/qmltimer.pro new file mode 100644 index 0000000..e7edd96 --- /dev/null +++ b/tests/auto/declarative/qmltimer/qmltimer.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +SOURCES += tst_qmltimer.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp new file mode 100644 index 0000000..15b558f --- /dev/null +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include + +class tst_qmltimer : public QObject +{ + Q_OBJECT +public: + tst_qmltimer(); + +private slots: + void notRepeating(); + void notRepeatingStart(); + void repeat(); + void triggeredOnStart(); + void triggeredOnStartRepeat(); +}; + +class TimerHelper : public QObject +{ + Q_OBJECT +public: + TimerHelper() : QObject(), count(0) + { + } + + int count; + +public slots: + void timeout() { + ++count; + } +}; + +#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) +// Increase wait as emulator startup can cause unexpected delays +#define TIMEOUT_TIMEOUT 2000 +#else +#define TIMEOUT_TIMEOUT 200 +#endif + +tst_qmltimer::tst_qmltimer() +{ +} + +void tst_qmltimer::notRepeating() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 100; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); +} + +void tst_qmltimer::notRepeatingStart() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 100 }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 0); + + timer->start(); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); +} + +void tst_qmltimer::repeat() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 100; repeat: true; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > 0); + int oldCount = helper.count; + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > oldCount); +} + +void tst_qmltimer::triggeredOnStart() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 100; running: true; triggeredOnStart: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QTest::qWait(1); + QCOMPARE(helper.count, 1); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 2); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 2); +} + +void tst_qmltimer::triggeredOnStartRepeat() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 100; running: true; triggeredOnStart: true; repeat: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QTest::qWait(1); + QCOMPARE(helper.count, 1); + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > 1); + int oldCount = helper.count; + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > oldCount); +} + +QTEST_MAIN(tst_qmltimer) + +#include "tst_qmltimer.moc" -- cgit v0.12 From 5b77922f3782de4b96d6cf07ebb88419de130eac Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 12:46:59 +1000 Subject: SameGame tutorial images --- doc/src/declarative/pics/declarative-adv-tutorial1.png | Bin 0 -> 81295 bytes doc/src/declarative/pics/declarative-adv-tutorial2.png | Bin 0 -> 170388 bytes doc/src/declarative/pics/declarative-adv-tutorial3.png | Bin 0 -> 220052 bytes doc/src/declarative/pics/declarative-adv-tutorial4.png | Bin 0 -> 273086 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/src/declarative/pics/declarative-adv-tutorial1.png create mode 100644 doc/src/declarative/pics/declarative-adv-tutorial2.png create mode 100644 doc/src/declarative/pics/declarative-adv-tutorial3.png create mode 100644 doc/src/declarative/pics/declarative-adv-tutorial4.png diff --git a/doc/src/declarative/pics/declarative-adv-tutorial1.png b/doc/src/declarative/pics/declarative-adv-tutorial1.png new file mode 100644 index 0000000..990a329 Binary files /dev/null and b/doc/src/declarative/pics/declarative-adv-tutorial1.png differ diff --git a/doc/src/declarative/pics/declarative-adv-tutorial2.png b/doc/src/declarative/pics/declarative-adv-tutorial2.png new file mode 100644 index 0000000..b410d50 Binary files /dev/null and b/doc/src/declarative/pics/declarative-adv-tutorial2.png differ diff --git a/doc/src/declarative/pics/declarative-adv-tutorial3.png b/doc/src/declarative/pics/declarative-adv-tutorial3.png new file mode 100644 index 0000000..e192772 Binary files /dev/null and b/doc/src/declarative/pics/declarative-adv-tutorial3.png differ diff --git a/doc/src/declarative/pics/declarative-adv-tutorial4.png b/doc/src/declarative/pics/declarative-adv-tutorial4.png new file mode 100644 index 0000000..03c9f46 Binary files /dev/null and b/doc/src/declarative/pics/declarative-adv-tutorial4.png differ -- cgit v0.12 From 19d080d319dccac15654294af80530bed9ef11ea Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 13:12:24 +1000 Subject: Switch Same Game tutorial to using snippets properly --- doc/src/declarative/advtutorial1.qdoc | 80 +--------- doc/src/declarative/advtutorial2.qdoc | 76 +--------- doc/src/declarative/advtutorial3.qdoc | 166 ++------------------- doc/src/declarative/advtutorial4.qdoc | 80 ++-------- .../declarative/pics/declarative-adv-tutorial4.gif | Bin 0 -> 58337629 bytes .../declarative/pics/declarative-adv-tutorial4.png | Bin 273086 -> 0 bytes .../tutorials/samegame/samegame1/Block.qml | 2 + .../tutorials/samegame/samegame1/Button.qml | 2 + .../tutorials/samegame/samegame1/samegame.qml | 2 + .../tutorials/samegame/samegame2/samegame.js | 2 + .../tutorials/samegame/samegame2/samegame.qml | 4 + .../tutorials/samegame/samegame3/Block.qml | 2 + .../tutorials/samegame/samegame3/Dialog.qml | 2 + .../tutorials/samegame/samegame3/samegame.js | 4 + .../tutorials/samegame/samegame3/samegame.qml | 6 + .../samegame/samegame4/content/BoomBlock.qml | 10 +- .../samegame/samegame4/content/samegame.js | 2 + 17 files changed, 73 insertions(+), 367 deletions(-) create mode 100644 doc/src/declarative/pics/declarative-adv-tutorial4.gif delete mode 100644 doc/src/declarative/pics/declarative-adv-tutorial4.png diff --git a/doc/src/declarative/advtutorial1.qdoc b/doc/src/declarative/advtutorial1.qdoc index b940986..48b32cd 100644 --- a/doc/src/declarative/advtutorial1.qdoc +++ b/doc/src/declarative/advtutorial1.qdoc @@ -10,46 +10,7 @@ The first step is to create the items in your application. In Same Game we have Here is the QML code for the basic elements. The game window: -\code -import Qt 4.6 - -Rectangle { - id: Screen - width: 490; height: 720 - - SystemPalette { id: activePalette; colorGroup: Qt.Active } - - Item { - width: parent.width; anchors.top: parent.top; anchors.bottom: ToolBar.top - - Image { - id: background - anchors.fill: parent; source: "pics/background.png" - fillMode: "PreserveAspectCrop" - } - } - - Rectangle { - id: ToolBar - color: activePalette.window - height: 32; width: parent.width - anchors.bottom: Screen.bottom - - Button { - id: btnA; text: "New Game"; onClicked: print("Implement me!"); - anchors.left: parent.left; anchors.leftMargin: 3 - anchors.verticalCenter: parent.verticalCenter - } - - Text { - id: Score - text: "Score: Who knows?"; font.bold: true - anchors.right: parent.right; anchors.rightMargin: 3 - anchors.verticalCenter: parent.verticalCenter - } - } -} -\endcode +\snippet declarative/tutorials/samegame/samegame1/samegame.qml 0 This gives you a basic game window, with room for the game canvas. A new game button and room to display the score. The one thing you may not recognize here @@ -59,49 +20,14 @@ feel you would use a QPushButton). Since we want a fully QML button, and the Fx primitives don't include a button, we had to write our own. Below is the code which we wrote to do this: -\code -import Qt 4.6 - -Rectangle { - id: Container - - signal clicked - property string text: "Button" - - color: activePalette.button; smooth: true - width: txtItem.width + 20; height: txtItem.height + 6 - border.width: 1; border.color: activePalette.darker(activePalette.button); radius: 8; - - gradient: Gradient { - GradientStop { - id: topGrad; position: 0.0 - color: if (mr.pressed) { activePalette.dark } else { activePalette.light } } - GradientStop { position: 1.0; color: activePalette.button } - } - - MouseRegion { id: mr; anchors.fill: parent; onClicked: Container.clicked() } +\snippet declarative/tutorials/samegame/samegame1/Button.qml 0 - Text { - id: txtItem; text: Container.text; anchors.centerIn: Container; color: activePalette.buttonText - } -} -\endcode Note that this Button component was written to be fairly generic, in case we want to use a similarly styled button later. And here is a simple block: -\code -import Qt 4.6 -Item { - id:block - - Image { id: img - source: "pics/redStone.png"; - anchors.fill: parent - } -} -\endcode +\snippet declarative/tutorials/samegame/samegame1/Block.qml 0 Since it doesn't do anything yet it's very simple, just an image. As the tutorial progresses and the block starts doing things the file will become diff --git a/doc/src/declarative/advtutorial2.qdoc b/doc/src/declarative/advtutorial2.qdoc index c17f9c4..2d2fe19 100644 --- a/doc/src/declarative/advtutorial2.qdoc +++ b/doc/src/declarative/advtutorial2.qdoc @@ -13,68 +13,7 @@ in the ECMA script, as opposed to using a Repeater. This adds enough script to justify a new file, samegame.js, the intial version of which is shown below -\code -//Note that X/Y referred to here are in game coordinates -var maxX = 10;//Nums are for tileSize 40 -var maxY = 15; -var tileSize = 40; -var maxIndex = maxX*maxY; -var board = new Array(maxIndex); -var tileSrc = "Block.qml"; -var component; - -//Index function used instead of a 2D array -function index(xIdx,yIdx) { - return xIdx + (yIdx * maxX); -} - -function initBoard() -{ - //Calculate board size - maxX = Math.floor(background.width/tileSize); - maxY = Math.floor(background.height/tileSize); - maxIndex = maxY*maxX; - - //Initialize Board - board = new Array(maxIndex); - for(xIdx=0; xIdx= maxX || xIdx < 0 || yIdx >= maxY || yIdx < 0) - return; - if(board[index(xIdx, yIdx)] == null) - return; - //If it's a valid tile, remove it and all connected (does nothing if it's not connected) - floodFill(xIdx,yIdx, -1); - if(fillFound <= 0) - return; - gameCanvas.score += (fillFound - 1) * (fillFound - 1); - shuffleDown(); - victoryCheck(); -} - -function victoryCheck() -{ - //awards bonuses for no tiles left - deservesBonus = true; - for(xIdx=maxX-1; xIdx>=0; xIdx--) - if(board[index(xIdx, maxY - 1)] != null) - deservesBonus = false; - if(deservesBonus) - gameCanvas.score += 500; - //Checks for game over - if(deservesBonus || !(floodMoveCheck(0,maxY-1, -1))) - dialog.show("Game Over. Your score is " + gameCanvas.score); -} -\endcode +\snippet declarative/tutorials/samegame/samegame3/samegame.js 1 +\snippet declarative/tutorials/samegame/samegame3/samegame.js 2 You'll notice them referring to the 'gameCanvas' item. This is an item that has been added to the QML for easy interfacing. It is placed next to the background image and replaces the background as the item to create the blocks in. Its code is shown below: -\code - Item { - id: gameCanvas - property int score: 0 - property int tileSize: 40 - - z: 20; anchors.centerIn: parent - width: parent.width - (parent.width % tileSize); - height: parent.height - (parent.height % tileSize); - - MouseRegion { - id: gameMR - anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); - } - } -\endcode + +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 1 This item is the exact size of the board, contains a score property, and a mouse region for input. The blocks are now created as its children, and its size is used as the noe determining board size. Since it needs to bind its size to a multiple of tileSize, tileSize needs to be moved into a QML property and out of the script file. It can still be accessed from the script. The mouse region simply calls handleClick(), which deals with the input events.Should those events cause the player to score, gameCanvas.score is updated. The score display text item has also been changed to bind its text property to gamecanvas.score. Note that if score was a global variable in the samegame.js file yo ucould not bind to it. You can only bind to QML properties. victoryCheck() mostly just updates score. But it also pops up a dialog saying 'Game Over' when the game is over. In this example we wanted a pure-QML, animated dialog, and since the Fx primitives set doesn't contain one, we wrote our own. Below is the code for the Dialog element, note how it's designed so as to be quite usable imperatively from within the script file: -\code -import Qt 4.6 - -Rectangle { - id: page - function forceClose() { - page.closed(); - page.opacity = 0; - } - function show(txt) { - MyText.text = txt; - page.opacity = 1; - } - signal closed(); - color: "white"; border.width: 1; width: MyText.width + 20; height: 60; - opacity: 0 - opacity: Behavior { - NumberAnimation { duration: 1000 } - } - Text { id: MyText; anchors.centerIn: parent; text: "Hello World!" } - MouseRegion { id: mr; anchors.fill: parent; onClicked: forceClose(); } -} -\endcode + +\snippet declarative/tutorials/samegame/samegame3/Dialog.qml 0 + And this is how it's used in the main QML file: -\code - Dialog { id: dialog; anchors.centerIn: parent; z: 21 } -\endcode + +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 2 + Combined with the line of code in victoryCheck, this causes a dialog to appear when the game is over, informing the user of that fact. We now have a working game! The blocks can be clicked, the player can score, and the game can end (and then you start a new one). Below is a screenshot of what has been accomplished so far: @@ -107,87 +43,11 @@ We now have a working game! The blocks can be clicked, the player can score, and Here is the QML code as it is now for the main file: -\code -import Qt 4.6 - -Rectangle { - id: Screen - width: 490; height: 720 - - SystemPalette { id: activePalette; colorGroup: Qt.Active } - Script { source: "samegame.js" } - - Item { - width: parent.width; anchors.top: parent.top; anchors.bottom: ToolBar.top - - Image { - id: background - anchors.fill: parent; source: "pics/background.png" - fillMode: "PreserveAspectCrop" - } - - Item { - id: gameCanvas - property int score: 0 - property int tileSize: 40 - - z: 20; anchors.centerIn: parent - width: parent.width - (parent.width % tileSize); - height: parent.height - (parent.height % tileSize); - - MouseRegion { - id: gameMR - anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); - } - } - } - - Dialog { id: dialog; anchors.centerIn: parent; z: 21 } - - Rectangle { - id: ToolBar - color: activePalette.window - height: 32; width: parent.width - anchors.bottom: Screen.bottom - - Button { - id: btnA; text: "New Game"; onClicked: initBoard(); - anchors.left: parent.left; anchors.leftMargin: 3 - anchors.verticalCenter: parent.verticalCenter - } - - Text { - id: Score - text: "Score: " + gameCanvas.score; font.bold: true - anchors.right: parent.right; anchors.rightMargin: 3 - anchors.verticalCenter: parent.verticalCenter - } - } -} -\endcode +\snippet declarative/tutorials/samegame/samegame3/samegame.qml 0 And the code for the block: -\code -import Qt 4.6 - -Item { - id:block - property int type: 0 - - Image { id: img - source: { - if(type == 0){ - "pics/redStone.png"; - } else if(type == 1) { - "pics/blueStone.png"; - } else { - "pics/greenStone.png"; - } - } - anchors.fill: parent - } -} -\endcode + +\snippet declarative/tutorials/samegame/samegame3/Block.qml 0 The game works, but it's a little boring right now. Where's the smooth animated transitions? Where's the high scores? If you were a QML expert you could have written these in for the first iteration, but in this tutorial they've been saved until the next chapter - where your application becomes alive! diff --git a/doc/src/declarative/advtutorial4.qdoc b/doc/src/declarative/advtutorial4.qdoc index 5ad1ec3..291d2f2 100644 --- a/doc/src/declarative/advtutorial4.qdoc +++ b/doc/src/declarative/advtutorial4.qdoc @@ -10,6 +10,7 @@ If you compare the samegame3 directory with samegame4, you'll noticed that we've \section2 Animated Blocks The most vital animations are that the blocks move fluidly around the board. QML has many tools for fluid behavior, and in this case we're going to use the Follow element. By having the script set targetX and targetY, instead of x and y directly, we can set the x and y of the block to a follow. SpringFollow is a property value source, which means that you can set a property to be one of these elements and it will automatically bind the property to the element's value. The SpringFollow's value follows another value over time, when the value it is tracking changes the SpringFollow's value will also change, but it will move smoothly there over time with a spring-like movement (based on the spring parameters specified). This is shown in the below snippet of code from Block.qml: + \code property int targetX: 0 property int targetY: 0 @@ -20,32 +21,11 @@ The most vital animations are that the blocks move fluidly around the board. QML We also have to change the samegame.js code, so that wherever it was setting the x or y it now sets targetX and targetY (including when creating the block). This simple change is all you need to get spring moving blocks that no longer teleport around the board. If you try doing just this though, you'll notice that they now never jump from one point to another, even in the initialization! This gives an odd effect of having them all jump out of the corner (0,0) on start up. We'd rather that they fall down from the top in rows. To do this, we disable the x Follow (but not the y follow) and only enable it after we've set the x in the createBlock function. The above snippet now becomes: -\code - property bool spawned: false - property int targetX: 0 - property int targetY: 0 - - x: SpringFollow { enabled: spawned; source: targetX; spring: 2; damping: 0.2 } - y: SpringFollow { source: targetY; spring: 2; damping: 0.2 } -\endcode +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 1 The next-most vital animation is a smooth exit. For this animation, we'll use a Behavior element. A Behavior is also a property value source, and it is much like SpringFollow except that it doesn't model the behavior of a spring. You specify how a Behavior transitions using the standard animations. As we want the blocks to smoothly fade in and out we'll set a Behavior on the block image's opacity, like so: -\code - Image { id: img - source: { - if(type == 0){ - "pics/redStone.png"; - } else if(type == 1) { - "pics/blueStone.png"; - } else { - "pics/greenStone.png"; - } - } - opacity: 0 - opacity: Behavior { NumberAnimation { properties:"opacity"; duration: 200 } } - anchors.fill: parent - } -\endcode + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 2 Note that the 'opacity: 0' makes it start out transparent. We could set the opacity in the script file when we create the blocks, but instead we use states (as this is useful for the next animation we'll implement). The below snippet is set on the root element of Block.qml: \code @@ -62,53 +42,25 @@ Note that the 'opacity: 0' makes it start out transparent. We could set the opac Now it will automatically fade in, as we set spawned to true already when implementing the block movement animations. To fade out, we set 'dying' to true instead of setting opacity to 0 when a block is destroyed (in the floodFill function). The least vital animations are a cool-looking particle effect when they get destroyed. First we create a Particles Element in the block, like so: -\code - Particles { id: particles - width:1; height:1; anchors.centerIn: parent; opacity: 0 - lifeSpan: 700; lifeSpanDeviation: 600; count:0; streamIn: false - angle: 0; angleDeviation: 360; velocity: 100; velocityDeviation:30 - source: { - if(type == 0){ - "pics/redStar.png"; - } else if (type == 1) { - "pics/blueStar.png"; - } else { - "pics/greenStar.png"; - } - } - } -\endcode + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 3 + To fully understand this you'll want to look at the Particles element documentation, but it's important to note that count is set to zero. -We next extend the 'dying' state, which triggers the particles by setting the count to non-zero. The code for that state looks like this: -\code - State{ name: "DeathState"; when: dying == true - PropertyChanges { target: particles; count: 50 } - PropertyChanges { target: particles; opacity: 1 } - PropertyChanges { target: particles; emitting: false } // i.e. emit only once - PropertyChanges { target: img; opacity: 0 } - } -\endcode -And now the game should be beautifully animated and smooth, with a subtle (or not-so-subtle) animation added for all of the player's actions. +We next extend the 'dying' state, which triggers the particles by setting the count to non-zero. The code for the states now look like this: + +\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 4 + +And now the game should be beautifully animated and smooth, with a subtle (or not-so-subtle) animation added for all of the player's actions. The end result is shown below: + +\image declarative-adv-tutorial4.gif \section2 Web-based High Scores Another extension we might want for the game is some way of storing and retriveing high scores. In this tutorial we'll show you how to integrate a web enabled high score storage into your QML application. The implementation we've done is very simple - the high score data is posted to a php script running on a server somewhere, and that server then stores it and displays it to visitors. You could request an XML or QML file from that same server, which contained and displayed the scores, but that's beyond the scope of this tutorial. For better high score data, we want the name and time of the player. The time is obtained in the script fairly simply, but we have to ask the player for their name. We thus re-use the dialog QML file to pop up a dialog asking for the player's name (and if they exit this dialog without entering it they have a way to opt out of posting their high score). When the dialog is closed, if the player entered their name we can send the data to the web service in the followign snippet out of the script file: -\code -function sendHighScore(name) { - var postman = new XMLHttpRequest() - var postData = "name="+name+"&score="+gameCanvas.score - +"&gridSize="+maxX+"x"+maxY +"&time="+Math.floor(timer/1000); - postman.open("POST", scoresURL, true); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been uploaded."); - } - } - postman.send(postData); -} -\endcode + +\snippet declarative/tutorials/samegame/samegame4/content/samegame.js 1 This is the same XMLHttpRequest() as you'll find in browser javascript, and can be used in the same way to dynamically get XML or QML from the web service to display the high scores. We don't worry about the response here though, we just post the high score data to the web server. If it had returned a QML file (or a URL to a QML file) you could instantiate it in much the same way as you did the blocks. diff --git a/doc/src/declarative/pics/declarative-adv-tutorial4.gif b/doc/src/declarative/pics/declarative-adv-tutorial4.gif new file mode 100644 index 0000000..a67666d Binary files /dev/null and b/doc/src/declarative/pics/declarative-adv-tutorial4.gif differ diff --git a/doc/src/declarative/pics/declarative-adv-tutorial4.png b/doc/src/declarative/pics/declarative-adv-tutorial4.png deleted file mode 100644 index 03c9f46..0000000 Binary files a/doc/src/declarative/pics/declarative-adv-tutorial4.png and /dev/null differ diff --git a/examples/declarative/tutorials/samegame/samegame1/Block.qml b/examples/declarative/tutorials/samegame/samegame1/Block.qml index 228ac4e..b76e61a 100644 --- a/examples/declarative/tutorials/samegame/samegame1/Block.qml +++ b/examples/declarative/tutorials/samegame/samegame1/Block.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Item { @@ -8,3 +9,4 @@ Item { anchors.fill: parent } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame1/Button.qml b/examples/declarative/tutorials/samegame/samegame1/Button.qml index 2354218..3846cf7 100644 --- a/examples/declarative/tutorials/samegame/samegame1/Button.qml +++ b/examples/declarative/tutorials/samegame/samegame1/Button.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Rectangle { @@ -23,3 +24,4 @@ Rectangle { id: txtItem; text: Container.text; anchors.centerIn: Container; color: activePalette.buttonText } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame1/samegame.qml b/examples/declarative/tutorials/samegame/samegame1/samegame.qml index d18718d..8b32cae 100644 --- a/examples/declarative/tutorials/samegame/samegame1/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame1/samegame.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Rectangle { @@ -36,3 +37,4 @@ Rectangle { } } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.js b/examples/declarative/tutorials/samegame/samegame2/samegame.js index 064d87e..2bf68b5 100644 --- a/examples/declarative/tutorials/samegame/samegame2/samegame.js +++ b/examples/declarative/tutorials/samegame/samegame2/samegame.js @@ -1,3 +1,4 @@ +//![0] //Note that X/Y referred to here are in game coordinates var maxX = 10;//Nums are for tileSize 40 var maxY = 15; @@ -57,3 +58,4 @@ function createBlock(xIdx,yIdx){ } return true; } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.qml b/examples/declarative/tutorials/samegame/samegame2/samegame.qml index e446fa4..78a3d83 100644 --- a/examples/declarative/tutorials/samegame/samegame2/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame2/samegame.qml @@ -5,7 +5,9 @@ Rectangle { width: 490; height: 720 SystemPalette { id: activePalette; colorGroup: Qt.Active } + //![2] Script { source: "samegame.js" } + //![2] Item { width: parent.width; anchors.top: parent.top; anchors.bottom: ToolBar.top @@ -23,11 +25,13 @@ Rectangle { height: 32; width: parent.width anchors.bottom: Screen.bottom + //![1] Button { id: btnA; text: "New Game"; onClicked: initBoard(); anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } + //![1] Text { id: Score diff --git a/examples/declarative/tutorials/samegame/samegame3/Block.qml b/examples/declarative/tutorials/samegame/samegame3/Block.qml index 2f28923..30a8d3a 100644 --- a/examples/declarative/tutorials/samegame/samegame3/Block.qml +++ b/examples/declarative/tutorials/samegame/samegame3/Block.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Item { @@ -17,3 +18,4 @@ Item { anchors.fill: parent } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame3/Dialog.qml b/examples/declarative/tutorials/samegame/samegame3/Dialog.qml index 401d211..5fe6aa0 100644 --- a/examples/declarative/tutorials/samegame/samegame3/Dialog.qml +++ b/examples/declarative/tutorials/samegame/samegame3/Dialog.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Rectangle { @@ -19,3 +20,4 @@ Rectangle { Text { id: MyText; anchors.centerIn: parent; text: "Hello World!" } MouseRegion { id: mr; anchors.fill: parent; onClicked: forceClose(); } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.js b/examples/declarative/tutorials/samegame/samegame3/samegame.js index 16b349d..8fecfef 100644 --- a/examples/declarative/tutorials/samegame/samegame3/samegame.js +++ b/examples/declarative/tutorials/samegame/samegame3/samegame.js @@ -72,6 +72,7 @@ function createBlock(xIdx,yIdx){ var fillFound;//Set after a floodFill call to the number of tiles found var floodBoard;//Set to 1 if the floodFill reaches off that node //NOTE: Be careful with vars named x,y, as the calling object's x,y are still in scope +//![1] function handleClick(x,y) { xIdx = Math.floor(x/gameCanvas.tileSize); @@ -88,6 +89,7 @@ function handleClick(x,y) shuffleDown(); victoryCheck(); } +//![1] function floodFill(xIdx,yIdx,type) { @@ -156,6 +158,7 @@ function shuffleDown() } } +//![2] function victoryCheck() { //awards bonuses for no tiles left @@ -169,6 +172,7 @@ function victoryCheck() if(deservesBonus || !(floodMoveCheck(0,maxY-1, -1))) dialog.show("Game Over. Your score is " + gameCanvas.score); } +//![2] //only floods up and right, to see if it can find adjacent same-typed tiles function floodMoveCheck(xIdx, yIdx, type) diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.qml b/examples/declarative/tutorials/samegame/samegame3/samegame.qml index ea43ab2..a0883da 100644 --- a/examples/declarative/tutorials/samegame/samegame3/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame3/samegame.qml @@ -1,3 +1,4 @@ +//![0] import Qt 4.6 Rectangle { @@ -16,6 +17,7 @@ Rectangle { fillMode: "PreserveAspectCrop" } + //![1] Item { id: gameCanvas property int score: 0 @@ -30,9 +32,12 @@ Rectangle { anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); } } + //![1] } + //![2] Dialog { id: dialog; anchors.centerIn: parent; z: 21 } + //![2] Rectangle { id: ToolBar @@ -54,3 +59,4 @@ Rectangle { } } } +//![0] diff --git a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml index a495cd0..7ad8b07 100644 --- a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml +++ b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml @@ -1,15 +1,18 @@ import Qt 4.6 Item { id:block + property int type: 0 property bool dying: false + //![1] property bool spawned: false - property int type: 0 property int targetX: 0 property int targetY: 0 x: SpringFollow { enabled: spawned; source: targetX; spring: 2; damping: 0.2 } y: SpringFollow { source: targetY; spring: 2; damping: 0.2 } + //![1] + //![2] Image { id: img source: { if(type == 0){ @@ -24,7 +27,9 @@ Item { id:block opacity: Behavior { NumberAnimation { properties:"opacity"; duration: 200 } } anchors.fill: parent } + //![2] + //![3] Particles { id: particles width:1; height:1; anchors.centerIn: parent; opacity: 0 lifeSpan: 700; lifeSpanDeviation: 600; count:0; streamIn: false @@ -39,7 +44,9 @@ Item { id:block } } } + //![3] + //![4] states: [ State{ name: "AliveState"; when: spawned == true && dying == false PropertyChanges { target: img; opacity: 1 } @@ -51,4 +58,5 @@ Item { id:block PropertyChanges { target: img; opacity: 0 } } ] + //![4] } diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js index cf55b59..ce9c169 100755 --- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js +++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js @@ -203,6 +203,7 @@ function createBlock(xIdx,yIdx){ return true; } +//![1] function sendHighScore(name) { var postman = new XMLHttpRequest() var postData = "name="+name+"&score="+gameCanvas.score @@ -215,3 +216,4 @@ function sendHighScore(name) { } postman.send(postData); } +//![1] -- cgit v0.12 From 07b3465405ccd59dc5c447cffc47cc1a17f674f0 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 15:18:06 +1000 Subject: Add three failing tests to the QML ECMAscript autotest Tests the creation, deletion and toString functions for QML objects. Task-number: QT-2252 --- .../qmlecmascript/data/dynamicCreation.helper.qml | 5 ++ .../qmlecmascript/data/dynamicCreation.qml | 16 +++++ .../qmlecmascript/data/dynamicDeletion.qml | 20 +++++++ .../declarative/qmlecmascript/data/qmlToString.qml | 11 ++++ .../qmlecmascript/tst_qmlecmascript.cpp | 69 ++++++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/qmlToString.qml diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml new file mode 100644 index 0000000..58ca26e --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml @@ -0,0 +1,5 @@ +import Qt.Test 1.0 + +MyQmlObject{ + objectName: "desolateObject" +} diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml new file mode 100644 index 0000000..f3eb75f --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "obj" + function createOne() + { + obj.objectProperty = createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"emptyObject"}', obj); + } + + function createTwo() + { + var component = createComponent('dynamicCreation.helper.qml'); + obj.objectProperty = component.createObject(); + } +} diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml b/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml new file mode 100644 index 0000000..618723f --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "obj" + function create() + { + obj.objectProperty = createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"emptyObject"}', obj); + } + + function killIt(wait) + { + if(obj.objectProperty == undefined || obj.objectProperty == null) + return; + if(wait > 0) + obj.objectProperty.destroy(wait); + else + obj.objectProperty.destroy(); + } +} diff --git a/tests/auto/declarative/qmlecmascript/data/qmlToString.qml b/tests/auto/declarative/qmlecmascript/data/qmlToString.qml new file mode 100644 index 0000000..ac296ce --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/qmlToString.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "objName" + function testToString() + { + obj.stringProperty = obj.toString(); + } + +} diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index d5d20b6..778b37f 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "testtypes.h" @@ -50,6 +51,9 @@ private slots: void outerBindingOverridesInnerBinding(); void aliasPropertyAndBinding(); void nonExistantAttachedObject(); + void dynamicCreation(); + void dynamicDestruction(); + void objectToString(); private: QmlEngine engine; @@ -531,6 +535,71 @@ void tst_qmlecmascript::aliasPropertyAndBinding() QCOMPARE(object->property("c3").toInt(), 19); } +/* + Test using createQmlObject to dynamically generate an item + Also using createComponent is tested. +*/ +void tst_qmlecmascript::dynamicCreation() +{ + QmlComponent component(&engine, TEST_FILE("dynamicCreation.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QObject *createdQmlObject = 0; + QObject *createdComponent = 0; + + QMetaObject::invokeMethod(object, "createOne"); + createdQmlObject = object->objectProperty(); + QVERIFY(createdQmlObject); + QCOMPARE(createdQmlObject->objectName(), QString("emptyObject")); + + QMetaObject::invokeMethod(object, "createTwo"); + createdComponent = object->objectProperty(); + QVERIFY(createdComponent); + QCOMPARE(createdQmlObject->objectName(), QString("desolateObject")); +} + +/* + Tests the destroy function +*/ +void tst_qmlecmascript::dynamicDestruction() +{ + QmlComponent component(&engine, TEST_FILE("dynamicDeletion.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QGuard createdQmlObject = 0; + + QMetaObject::invokeMethod(object, "create"); + createdQmlObject = object->objectProperty(); + QVERIFY(createdQmlObject); + QCOMPARE(createdQmlObject->objectName(), QString("emptyObject")); + + QMetaObject::invokeMethod(object, "killIt", Q_ARG(int, 0)); + QVERIFY(createdQmlObject); + QTest::qWait(0); + QVERIFY(!createdQmlObject); + + QMetaObject::invokeMethod(object, "create"); + QVERIFY(createdQmlObject); + QMetaObject::invokeMethod(object, "killIt", Q_ARG(int, 100)); + QVERIFY(createdQmlObject); + QTest::qWait(0); + QVERIFY(createdQmlObject); + QTest::qWait(100); + QVERIFY(!createdQmlObject); +} + +/* + tests that id.toString() works +*/ +void tst_qmlecmascript::objectToString() +{ + QmlComponent component(&engine, TEST_FILE("qmlToString.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QMetaObject::invokeMethod(object, "testToString"); + QVERIFY(object->stringProperty().startsWith("Qml Object, \"objName\" MyQmlObject_QML_15")); +} + QTEST_MAIN(tst_qmlecmascript) #include "tst_qmlecmascript.moc" -- cgit v0.12 From 0e91a2e5cb940f5f677345a2f811061b75b32635 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 7 Oct 2009 07:29:06 +0200 Subject: Compile on Symbian. --- src/declarative/util/qmllistmodel.cpp | 80 +++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 69bed25..062ab48 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -239,41 +239,8 @@ struct ModelNode return objectCache; } - void setListValue(const QScriptValue& valuelist) { - QScriptValueIterator it(valuelist); - values.clear(); - while (it.hasNext()) { - it.next(); - ModelNode *value = new ModelNode; - QScriptValue v = it.value(); - if (v.isArray()) { - value->setListValue(v); - } else if (v.isObject()) { - value->setObjectValue(v); - } else { - value->values << v.toVariant(); - } - values.append(qVariantFromValue(value)); - - } - } - - void setObjectValue(const QScriptValue& valuemap) { - QScriptValueIterator it(valuemap); - while (it.hasNext()) { - it.next(); - ModelNode *value = new ModelNode; - QScriptValue v = it.value(); - if (v.isArray()) { - value->setListValue(v); - } else if (v.isObject()) { - value->setObjectValue(v); - } else { - value->values << v.toVariant(); - } - properties.insert(it.name(),value); - } - } + void setObjectValue(const QScriptValue& valuemap); + void setListValue(const QScriptValue& valuelist); void setProperty(const QString& prop, const QVariant& val) { QHash::const_iterator it = properties.find(prop); @@ -292,6 +259,48 @@ struct ModelNode ModelObject *objectCache; }; +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(ModelNode *) + +QT_BEGIN_NAMESPACE +void ModelNode::setObjectValue(const QScriptValue& valuemap) { + QScriptValueIterator it(valuemap); + while (it.hasNext()) { + it.next(); + ModelNode *value = new ModelNode; + QScriptValue v = it.value(); + if (v.isArray()) { + value->setListValue(v); + } else if (v.isObject()) { + value->setObjectValue(v); + } else { + value->values << v.toVariant(); + } + properties.insert(it.name(),value); + } +} + +void ModelNode::setListValue(const QScriptValue& valuelist) { + QScriptValueIterator it(valuelist); + values.clear(); + while (it.hasNext()) { + it.next(); + ModelNode *value = new ModelNode; + QScriptValue v = it.value(); + if (v.isArray()) { + value->setListValue(v); + } else if (v.isObject()) { + value->setObjectValue(v); + } else { + value->values << v.toVariant(); + } + values.append(qVariantFromValue(value)); + + } +} + + ModelObject::ModelObject() : _mo(new QmlOpenMetaObject(this)) { @@ -846,7 +855,6 @@ ModelNode::~ModelNode() QT_END_NAMESPACE -Q_DECLARE_METATYPE(ModelNode *) QML_DECLARE_TYPE(QmlListElement) #include "qmllistmodel.moc" -- cgit v0.12 From 833ca7b4f038b92e1bdbc6368ec73c9eb4568f7c Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 7 Oct 2009 15:36:56 +1000 Subject: Update 'hello world' tutorial. --- doc/src/declarative/qmlintro.qdoc | 2 +- doc/src/declarative/qmlreference.qdoc | 2 +- doc/src/declarative/tutorial.qdoc | 12 +- doc/src/declarative/tutorial1.qdoc | 62 +++------- doc/src/declarative/tutorial2.qdoc | 135 ++++++--------------- doc/src/declarative/tutorial3.qdoc | 124 +++++-------------- doc/src/images/declarative-tutorial1.png | Bin 3025 -> 3577 bytes doc/src/images/declarative-tutorial2.png | Bin 3050 -> 3913 bytes doc/src/images/declarative-tutorial3_animation.gif | Bin 38111 -> 301974 bytes .../tutorials/helloworld/t1/tutorial1.qml | 20 +-- .../declarative/tutorials/helloworld/t2/Cell.qml | 26 +++- .../tutorials/helloworld/t2/tutorial2.qml | 34 +++--- .../declarative/tutorials/helloworld/t3/Cell.qml | 15 ++- .../tutorials/helloworld/t3/tutorial3.qml | 79 ++++++------ 14 files changed, 192 insertions(+), 319 deletions(-) diff --git a/doc/src/declarative/qmlintro.qdoc b/doc/src/declarative/qmlintro.qdoc index e87b7a8..ef84b8e 100644 --- a/doc/src/declarative/qmlintro.qdoc +++ b/doc/src/declarative/qmlintro.qdoc @@ -153,7 +153,7 @@ Item { } \endcode -\section3 The 'id' property +\section3 The \c id property The \c id property is a special property of type \e id. Assigning an id to an object allows you to refer to it elsewhere. diff --git a/doc/src/declarative/qmlreference.qdoc b/doc/src/declarative/qmlreference.qdoc index bb0d61a..b26fc64 100644 --- a/doc/src/declarative/qmlreference.qdoc +++ b/doc/src/declarative/qmlreference.qdoc @@ -18,7 +18,7 @@ Getting Started: \list \o \l {Introduction to the QML language} (in progress) - \o \l {tutorial}{Tutorial: 'Hello World'} + \o \l {tutorial}{Tutorial: 'Hello world!'} \o \l {tutorials-declarative-contacts.html}{Tutorial: 'Introduction to QML'} \o \l {qmlexamples}{Examples} \endlist diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc index a2a34b9..b59384c 100644 --- a/doc/src/declarative/tutorial.qdoc +++ b/doc/src/declarative/tutorial.qdoc @@ -2,7 +2,11 @@ \page tutorial.html \title Tutorial -This tutorial gives an introduction to QML. It doesn't cover everything; the emphasis is on teaching the key principles, and features are introduced as needed. +This tutorial gives an introduction to QML. It doesn't cover everything; the emphasis is on teaching the key principles, +and features are introduced as needed. + +Through the different steps of this tutorial we will learn about QML basic types, we will create our own QML component +with properties and signals, and we will create a simple animation with the help of states and transitions. Chapter one starts with a minimal "Hello world" program and the following chapters introduce new concepts. @@ -11,9 +15,9 @@ The tutorial's source code is located in the $QTDIR/examples/declarative/tutoria Tutorial chapters: \list -\o \l {tutorial1}{Tutorial 1} -\o \l {tutorial2}{Tutorial 2} -\o \l {tutorial3}{Tutorial 3} +\o \l {tutorial1}{Tutorial 1 - Basic Types} +\o \l {tutorial2}{Tutorial 2 - QML Component} +\o \l {tutorial3}{Tutorial 3 - States and Transitions} \endlist */ diff --git a/doc/src/declarative/tutorial1.qdoc b/doc/src/declarative/tutorial1.qdoc index d4f1095..f46c59d 100644 --- a/doc/src/declarative/tutorial1.qdoc +++ b/doc/src/declarative/tutorial1.qdoc @@ -1,68 +1,46 @@ /*! \page tutorial1.html -\title Tutorial 1 - Hello World! +\title Tutorial 1 - Basic Types \target tutorial1 -This first program is a simple "Hello world" example. The picture below is a screenshot of this program. +This first program is a very simple "Hello world" example that introduces some basic QML concepts. +The picture below is a screenshot of this program. \image declarative-tutorial1.png Here is the QML code for the application: -\code -Rectangle { - id: Page - width: 480 - height: 200 - color: "LightGrey" - Text { - id: HelloText - text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: Page.horizontalCenter - } -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 0 \section1 Walkthrough +\section2 Import + +First, we need to import the types that we need for this example. Most QML files will import the built-in QML +types (like \l{Rectangle}, \l{Image}, ...) that come with Qt with: + +\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 3 + \section2 Rectangle element -\code -Rectangle { - id: Page - width: 480 - height: 200 - color: "LightGrey" -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 1 -First, we declare a root element of type \l Rectangle. It is one of the basic building blocks you can use to create an application in QML. -We give it an id to be able to refer to it later. In this case, we call it \e Page. We also set the \c width, \c height and \c color properties. -The \l Rectangle element contains many other properties (such as \c x and \c y), but these are left at their default values. +We declare a root element of type \l{Rectangle}. It is one of the basic building blocks you can use to create an application in QML. +We give it an \c{id} to be able to refer to it later. In this case, we call it \e page. We also set the \c width, \c height and \c color properties. +The \l{Rectangle} element contains many other properties (such as \c x and \c y), but these are left at their default values. \section2 Text element -\code -Text { - id: HelloText - text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: Page.horizontalCenter -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 2 -We add a text element as a child of our root element to display the text 'Hello world!'. +We add a \l Text element as a child of our root element that will display the text 'Hello world!'. The \c y property is used to position the text vertically at 30 pixels from the top of its parent. -The \c font.pointSize and \c font.bold properties are related to fonts and use the \e 'dot' notation. +The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{Dot Properties}{dot notation}. -The \c anchors.horizontalCenter property refers to the horizontal center of an element. In this case, we specify that our text element should be horizontally centered in the \e Page element. +The \c anchors.horizontalCenter property refers to the horizontal center of an element. +In this case, we specify that our text element should be horizontally centered in the \e page element (see \l{anchor-layout}{Anchor-based Layout}). \section2 Viewing the example diff --git a/doc/src/declarative/tutorial2.qdoc b/doc/src/declarative/tutorial2.qdoc index c6fd06b..21b5ebd 100644 --- a/doc/src/declarative/tutorial2.qdoc +++ b/doc/src/declarative/tutorial2.qdoc @@ -1,130 +1,69 @@ /*! \page tutorial2.html -\title Tutorial 2 - Some colors +\title Tutorial 2 - QML Component \target tutorial2 This chapter adds a color picker to change the color of the text. \image declarative-tutorial2.png -Our color picker is made of many cells with different colors. To avoid writing the same code many times, we first create a new \c Cell component with a color property (see \l components). +Our color picker is made of six cells with different colors. +To avoid writing the same code multiple times, we first create a new \c Cell component. +A component provides a way of defining a new type that we can re-use in other QML files. +A QML component is like a black-box and interacts with the outside world through properties, signals and slots and is generally +defined in its own QML file (for more details, see \l components). Here is the QML code for \c Cell.qml: -\code -Item { - property var color - - id: CellContainer - width: 40 - height: 25 - - Rectangle { - anchors.fill: parent - color: CellContainer.color - } - MouseRegion { - anchors.fill: parent - onClicked: { HelloText.color = CellContainer.color } - } -} -\endcode - -Then, we use our \c Cell component to create the color picker in the QML code for the application: - -\code -Rectangle { - id: Page - width: 480 - height: 200 - color: "LightGrey" - Text { - id: HelloText - text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: Page.horizontalCenter - } - Grid { - id: ColorPicker - x: 0 - anchors.bottom: Page.bottom - width: 120; height: 50 - rows: 2; columns: 3 - Cell { color: "#ff0000" } - Cell { color: "#00ff00" } - Cell { color: "#0000ff" } - Cell { color: "#ffff00" } - Cell { color: "#00ffff" } - Cell { color: "#ff00ff" } - } -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 0 \section1 Walkthrough \section2 The Cell Component -\code -Item { - id: CellContainer - width: 40 - height: 25 -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 1 -The root element of our component is an \c Item. It is the most basic element in QML and is often used as a container for other elements. +The root element of our component is an \l Item with the \c id \e container. +An \l Item is the most basic visual element in QML and is often used as a container for other elements. -\code -property var color -\endcode +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 4 -We declare a \c color property. This property is accessible from \e outside our component, this allows us to instantiate the cells with different colors. +We declare a \c color property. This property is accessible from \e outside our component, this allows us +to instantiate the cells with different colors. +This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{Properties}). -\code -Rectangle { - anchors.fill: parent - color: CellContainer.color -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 5 -Our cell component is basically a colored rectangle. +We want our component to also have a signal that we call \e clicked with a \e color parameter. +We will use this signal to change the color of the text in the main QML file later. -The \c anchors.fill property is a convenient way to set the size of an element. In this case the \c Rectangle will have the same size as its parent. +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 2 -We bind the \c color property of this \c Rectangle to the color property of our component. +Our cell component is basically a colored rectangle with the \c id \e rectangle. -\code -MouseRegion { - anchors.fill: parent - onClicked: { HelloText.color = CellContainer.color } -} -\endcode +The \c anchors.fill property is a convenient way to set the size of an element. +In this case the rectangle will have the same size as its parent (see \l{anchor-layout}{Anchor-based Layout}). -In order to change the color of the text when clicking on a cell, we create a \c MouseRegion element with the same size as its parent. +\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 3 -The \c onClicked property sets the \c color property of the element named \e HelloText to our cell color. +In order to change the color of the text when clicking on a cell, we create a \l MouseRegion element with +the same size as its parent. + +A \l MouseRegion defines a signal called \e clicked. +When this signal is triggered we want to emit our own \e clicked signal with the color as parameter. \section2 The main QML file -\code -Grid { - id: ColorPicker - x: 0 - anchors.bottom: Page.bottom - width: 120; height: 50 - rows: 2; columns: 3 - Cell { color: "#ff0000" } - Cell { color: "#00ff00" } - Cell { color: "#0000ff" } - Cell { color: "#ffff00" } - Cell { color: "#00ffff" } - Cell { color: "#ff00ff" } -} -\endcode - -In the main QML file, the only thing we have to do is to create a color picker by putting 6 cells with different colors in a grid. +In our main QML file, we use our \c Cell component to create the color picker: + +\snippet examples/declarative/tutorials/helloworld/t2/tutorial2.qml 0 + +We create the color picker by putting 6 cells with different colors in a grid. + +\snippet examples/declarative/tutorials/helloworld/t2/tutorial2.qml 1 + +When the \e clicked signal of our cell is triggered, we want to set the color of the text to the color passed as a parameter. +We can react to any signal of our component through a property of the name \e 'onSignalName' (see \l{Signal Handlers}). [Previous: \l tutorial1] [Next: \l tutorial3] diff --git a/doc/src/declarative/tutorial3.qdoc b/doc/src/declarative/tutorial3.qdoc index a0d842c..21b7ae5 100644 --- a/doc/src/declarative/tutorial3.qdoc +++ b/doc/src/declarative/tutorial3.qdoc @@ -1,111 +1,43 @@ -/*! +/*! \page tutorial3.html -\title Tutorial 3 - States +\title Tutorial 3 - States and Transitions \target tutorial3 -In this chapter, we make this example a little bit more dynamic by introducing states. +In this chapter, we make this example a little bit more dynamic by introducing states and transitions. -We want our text to jump at the bottom of the screen and become red when clicked. +We want our text to move to the bottom of the screen, rotate and become red when clicked. \image declarative-tutorial3_animation.gif Here is the QML code: -\code -Rectangle { - id: Page - width: 480 - height: 200 - color: "LightGrey" - Text { - id: HelloText - text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: Page.horizontalCenter - states: [ - State { - name: "down" - when: MouseRegion.pressed == true - PropertyChanges { target: HelloText; y: 160; color: "red" } - } - ] - transitions: [ - Transition { - from: "*" - to: "down" - reversible: true - ParallelAnimation { - NumberAnimation { - properties: "y" - duration: 500 - easing: "easeOutBounce" - } - ColorAnimation { property: "color"; duration: 500 } - } - } - ] - } - MouseRegion { id: MouseRegion; anchors.fill: HelloText } - Grid { - id: ColorPicker - x: 0 - anchors.bottom: Page.bottom - width: 120; height: 50 - rows: 2; columns: 3 - Cell { color: "#ff0000" } - Cell { color: "#00ff00" } - Cell { color: "#0000ff" } - Cell { color: "#ffff00" } - Cell { color: "#00ffff" } - Cell { color: "#ff00ff" } - } -} -\endcode +\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 0 \section1 Walkthrough -\code -states: [ - State { - name: "down" - when: MouseRegion.pressed == true - PropertyChanges { target: HelloText; y: 160; color: "red" } - } -] -\endcode - -First, we create a new state \e down for our text element. This state will be activated when MouseRegion is pressed, and deactivated when it is released. - -The \e down state includes a set of property changes from our implicit \e {default state} (the items as they were initially defined in the QML). Specifically, we set the \c y property of the text to 160 and the \c color to red. - -\code -Transition { - from: "*" - to: "down" - reversible: true -} -\endcode - -Because we don't want the text to appear at the bottom instantly but rather move smoothly, we add a transition between our two states. - -\c from and \c to define the states between which the transition will run. In this case, we want a transition from any state to our \e down state. - -Because we want the same transition to be run in reverse when changing back from the \e down state to the default state, we set \c reversible to \c true. This is equivalent to writing the two transitions separately. - -\code -ParallelAnimation { - NumberAnimation { - properties: "y" - duration: 500 - easing: "easeOutBounce" - } - ColorAnimation { property: "color"; duration: 500 } -} -\endcode - -The \c ParallelAnimation element makes sure that the two animations (color and position) will start at the same time. We could also run them one after the other by using \c SequentialAnimation instead. +\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 2 + +First, we create a new \e down state for our text element. +This state will be activated when the \l MouseRegion is pressed, and deactivated when it is released. + +The \e down state includes a set of property changes from our implicit \e {default state} +(the items as they were initially defined in the QML). +Specifically, we set the \c y property of the text to \c 160, the rotation to \c 180 and the \c color to red. + +\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 3 + +Because we don't want the text to appear at the bottom instantly but rather move smoothly, +we add a transition between our two states. + +\c from and \c to define the states between which the transition will run. +In this case, we want a transition from the default state to our \e down state. + +Because we want the same transition to be run in reverse when changing back from the \e down state to the default state, +we set \c reversible to \c true. +This is equivalent to writing the two transitions separately. + +The \l ParallelAnimation element makes sure that the two types of animations (number and color) start at the same time. +We could also run them one after the other by using \l SequentialAnimation instead. For more details on states and transitions, see \l {states-transitions}{States and Transitions}. diff --git a/doc/src/images/declarative-tutorial1.png b/doc/src/images/declarative-tutorial1.png index ea0000f..c9d3844 100644 Binary files a/doc/src/images/declarative-tutorial1.png and b/doc/src/images/declarative-tutorial1.png differ diff --git a/doc/src/images/declarative-tutorial2.png b/doc/src/images/declarative-tutorial2.png index 0538451..835484a 100644 Binary files a/doc/src/images/declarative-tutorial2.png and b/doc/src/images/declarative-tutorial2.png differ diff --git a/doc/src/images/declarative-tutorial3_animation.gif b/doc/src/images/declarative-tutorial3_animation.gif index d2d4c63..80b78de 100644 Binary files a/doc/src/images/declarative-tutorial3_animation.gif and b/doc/src/images/declarative-tutorial3_animation.gif differ diff --git a/examples/declarative/tutorials/helloworld/t1/tutorial1.qml b/examples/declarative/tutorials/helloworld/t1/tutorial1.qml index e2c6650..93d3c34 100644 --- a/examples/declarative/tutorials/helloworld/t1/tutorial1.qml +++ b/examples/declarative/tutorials/helloworld/t1/tutorial1.qml @@ -1,16 +1,22 @@ +//![0] +//![3] import Qt 4.6 +//![3] +//![1] Rectangle { id: page - width: 480 - height: 200 - color: "LightGrey" + width: 500; height: 200 + color: "lightgray" +//![1] + +//![2] Text { id: helloText text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: page.horizontalCenter + font.pointSize: 24; font.bold: true + y: 30; anchors.horizontalCenter: page.horizontalCenter } +//![2] } +//![0] diff --git a/examples/declarative/tutorials/helloworld/t2/Cell.qml b/examples/declarative/tutorials/helloworld/t2/Cell.qml index bfd835d..ab6e565 100644 --- a/examples/declarative/tutorials/helloworld/t2/Cell.qml +++ b/examples/declarative/tutorials/helloworld/t2/Cell.qml @@ -1,18 +1,32 @@ +//![0] import Qt 4.6 +//![1] Item { - property var color + id: container +//![4] + property alias color: rectangle.color +//![4] +//![5] + signal clicked(string color) +//![5] - id: cellContainer - width: 40 - height: 25 + width: 40; height: 25 +//![1] +//![2] Rectangle { + id: rectangle + border.color: "white" anchors.fill: parent - color: cellContainer.color } +//![2] + +//![3] MouseRegion { anchors.fill: parent - onClicked: { helloText.color = cellContainer.color } + onClicked: container.clicked(container.color) } +//![3] } +//![0] diff --git a/examples/declarative/tutorials/helloworld/t2/tutorial2.qml b/examples/declarative/tutorials/helloworld/t2/tutorial2.qml index aee9032..99889d7 100644 --- a/examples/declarative/tutorials/helloworld/t2/tutorial2.qml +++ b/examples/declarative/tutorials/helloworld/t2/tutorial2.qml @@ -1,29 +1,31 @@ +//![0] import Qt 4.6 Rectangle { id: page - width: 480 - height: 200 - color: "LightGrey" + width: 500; height: 200 + color: "lightgray" + Text { id: helloText text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: page.horizontalCenter + font.pointSize: 24; font.bold: true + y: 30; anchors.horizontalCenter: page.horizontalCenter } + Grid { id: colorPicker - x: 0 anchors.bottom: page.bottom - width: 120; height: 50 - rows: 2; columns: 3 - Cell { color: "#ff0000" } - Cell { color: "#00ff00" } - Cell { color: "#0000ff" } - Cell { color: "#ffff00" } - Cell { color: "#00ffff" } - Cell { color: "#ff00ff" } + rows: 2; columns: 3; spacing: 3 + +//![1] + Cell { color: "red"; onClicked: helloText.color = color } +//![1] + Cell { color: "green"; onClicked: helloText.color = color } + Cell { color: "blue"; onClicked: helloText.color = color } + Cell { color: "yellow"; onClicked: helloText.color = color } + Cell { color: "steelblue"; onClicked: helloText.color = color } + Cell { color: "black"; onClicked: helloText.color = color } } } +//![0] diff --git a/examples/declarative/tutorials/helloworld/t3/Cell.qml b/examples/declarative/tutorials/helloworld/t3/Cell.qml index 6feb7a9..578369d 100644 --- a/examples/declarative/tutorials/helloworld/t3/Cell.qml +++ b/examples/declarative/tutorials/helloworld/t3/Cell.qml @@ -1,17 +1,20 @@ import Qt 4.6 Item { - property var color + id: container + property alias color: rectangle.color + signal clicked(string color) + + width: 40; height: 25 - id: cellContainer - width: 40 - height: 25 Rectangle { + id: rectangle + border.color: "white" anchors.fill: parent - color: cellContainer.color } + MouseRegion { anchors.fill: parent - onClicked: { helloText.color = cellContainer.color } + onClicked: container.clicked(container.color) } } diff --git a/examples/declarative/tutorials/helloworld/t3/tutorial3.qml b/examples/declarative/tutorials/helloworld/t3/tutorial3.qml index b80065d..d641eba 100644 --- a/examples/declarative/tutorials/helloworld/t3/tutorial3.qml +++ b/examples/declarative/tutorials/helloworld/t3/tutorial3.qml @@ -1,56 +1,51 @@ +//![0] import Qt 4.6 Rectangle { id: page - width: 480 - height: 200 - color: "LightGrey" + width: 500; height: 200 + color: "lightgray" + Text { id: helloText text: "Hello world!" - font.pointSize: 24 - font.bold: true - y: 30 - anchors.horizontalCenter: page.horizontalCenter - states: [ - State { - name: "down" - when: mouseRegion.pressed == true - PropertyChanges { - target: helloText - y: 160 - color: "red" - } - } - ] - transitions: [ - Transition { - from: "*" - to: "down" - reversible: true - ParallelAnimation { - NumberAnimation { - properties: "y" - duration: 500 - easing: "easeOutBounce" - } - ColorAnimation { property: "color"; duration: 500 } - } + font.pointSize: 24; font.bold: true + y: 30; anchors.horizontalCenter: page.horizontalCenter + transformOrigin: "Center" + +//![1] + MouseRegion { id: mouseRegion; anchors.fill: parent } +//![1] + +//![2] + states: State { + name: "down"; when: mouseRegion.pressed == true + PropertyChanges { target: helloText; y: 160; rotation: 180; color: "red" } + } +//![2] + +//![3] + transitions: Transition { + from: ""; to: "down"; reversible: true + ParallelAnimation { + NumberAnimation { properties: "y,rotation"; duration: 500; easing: "easeInOutQuad" } + ColorAnimation { property: "color"; duration: 500 } } - ] + } +//![3] } - MouseRegion { id: mouseRegion; anchors.fill: helloText } + Grid { id: colorPicker - x: 0 anchors.bottom: page.bottom - width: 120; height: 50 - rows: 2; columns: 3 - Cell { color: "#ff0000" } - Cell { color: "#00ff00" } - Cell { color: "#0000ff" } - Cell { color: "#ffff00" } - Cell { color: "#00ffff" } - Cell { color: "#ff00ff" } + rows: 2; columns: 3; spacing: 3 + + Cell { color: "red"; onClicked: helloText.color = color } + Cell { color: "green"; onClicked: helloText.color = color } + Cell { color: "blue"; onClicked: helloText.color = color } + Cell { color: "yellow"; onClicked: helloText.color = color } + Cell { color: "steelblue"; onClicked: helloText.color = color } + Cell { color: "black"; onClicked: helloText.color = color } } } +//![0] -- cgit v0.12 From 8b0cac9179de4d1cb34b9f17932d34cef3cd4f5b Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 15:42:53 +1000 Subject: Get two of those new autotests to pass. The third will not pass until QT-2240 is fixed. --- .../qmlecmascript/data/dynamicCreation.helper.qml | 4 ++-- .../qmlecmascript/data/dynamicCreation.qml | 2 +- .../qmlecmascript/data/dynamicDeletion.qml | 14 +++++++------- .../declarative/qmlecmascript/tst_qmlecmascript.cpp | 20 +++++++++----------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml index 58ca26e..b26d6e1 100644 --- a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml +++ b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.helper.qml @@ -1,5 +1,5 @@ -import Qt.Test 1.0 +import Qt.test 1.0 MyQmlObject{ - objectName: "desolateObject" + objectName: "objectTwo" } diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml index f3eb75f..ef39590 100644 --- a/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml +++ b/tests/auto/declarative/qmlecmascript/data/dynamicCreation.qml @@ -5,7 +5,7 @@ MyQmlObject{ objectName: "obj" function createOne() { - obj.objectProperty = createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"emptyObject"}', obj); + obj.objectProperty = createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"objectOne"}', obj); } function createTwo() diff --git a/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml b/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml index 618723f..ba87b32 100644 --- a/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml +++ b/tests/auto/declarative/qmlecmascript/data/dynamicDeletion.qml @@ -8,13 +8,13 @@ MyQmlObject{ obj.objectProperty = createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"emptyObject"}', obj); } - function killIt(wait) + function killOther() { - if(obj.objectProperty == undefined || obj.objectProperty == null) - return; - if(wait > 0) - obj.objectProperty.destroy(wait); - else - obj.objectProperty.destroy(); + obj.objectProperty.destroy(100); + } + + function killMe() + { + obj.destroy();//Must not segfault } } diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index 778b37f..3f01192 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -550,12 +550,12 @@ void tst_qmlecmascript::dynamicCreation() QMetaObject::invokeMethod(object, "createOne"); createdQmlObject = object->objectProperty(); QVERIFY(createdQmlObject); - QCOMPARE(createdQmlObject->objectName(), QString("emptyObject")); + QCOMPARE(createdQmlObject->objectName(), QString("objectOne")); QMetaObject::invokeMethod(object, "createTwo"); createdComponent = object->objectProperty(); QVERIFY(createdComponent); - QCOMPARE(createdQmlObject->objectName(), QString("desolateObject")); + QCOMPARE(createdComponent->objectName(), QString("objectTwo")); } /* @@ -564,7 +564,7 @@ void tst_qmlecmascript::dynamicCreation() void tst_qmlecmascript::dynamicDestruction() { QmlComponent component(&engine, TEST_FILE("dynamicDeletion.qml")); - MyQmlObject *object = qobject_cast(component.create()); + QGuard object = qobject_cast(component.create()); QVERIFY(object != 0); QGuard createdQmlObject = 0; @@ -573,19 +573,17 @@ void tst_qmlecmascript::dynamicDestruction() QVERIFY(createdQmlObject); QCOMPARE(createdQmlObject->objectName(), QString("emptyObject")); - QMetaObject::invokeMethod(object, "killIt", Q_ARG(int, 0)); - QVERIFY(createdQmlObject); - QTest::qWait(0); - QVERIFY(!createdQmlObject); - - QMetaObject::invokeMethod(object, "create"); - QVERIFY(createdQmlObject); - QMetaObject::invokeMethod(object, "killIt", Q_ARG(int, 100)); + QMetaObject::invokeMethod(object, "killOther"); QVERIFY(createdQmlObject); QTest::qWait(0); QVERIFY(createdQmlObject); QTest::qWait(100); QVERIFY(!createdQmlObject); + + QMetaObject::invokeMethod(object, "killMe"); + QVERIFY(object); + QTest::qWait(0); + QVERIFY(!object); } /* -- cgit v0.12 From d16640f186f0588935ce99a14927cdf6f2a2fa98 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 16:38:31 +1000 Subject: Smaller gif file for the advanced tutorial --- .../declarative/pics/declarative-adv-tutorial4.gif | Bin 58337629 -> 1687445 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/declarative/pics/declarative-adv-tutorial4.gif b/doc/src/declarative/pics/declarative-adv-tutorial4.gif index a67666d..827458d 100644 Binary files a/doc/src/declarative/pics/declarative-adv-tutorial4.gif and b/doc/src/declarative/pics/declarative-adv-tutorial4.gif differ -- cgit v0.12 From 605f47d61c44e1219811b2d68d3fcb51ab284015 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 7 Oct 2009 16:51:00 +1000 Subject: Fix QFxTextInput It was accepting input on both press and release, for some reason --- src/declarative/fx/qfxtextinput.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/fx/qfxtextinput.cpp b/src/declarative/fx/qfxtextinput.cpp index b7b155a..05d2260 100644 --- a/src/declarative/fx/qfxtextinput.cpp +++ b/src/declarative/fx/qfxtextinput.cpp @@ -594,6 +594,7 @@ bool QFxTextInput::event(QEvent* ev) bool handled = false; switch(ev->type()){ case QEvent::KeyPress: + case QEvent::KeyRelease://###Should the control be doing anything with release? case QEvent::GraphicsSceneMousePress: break; default: -- cgit v0.12 From 28e0f484cfb2b677661f0cb1a90a7b88d8f46f03 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 7 Oct 2009 17:07:55 +1000 Subject: move files to avoid duplication. --- doc/src/declarative/tutorial1.qdoc | 17 ++++---- doc/src/declarative/tutorial2.qdoc | 16 +++---- doc/src/declarative/tutorial3.qdoc | 7 ++- examples/declarative/tutorials/helloworld/Cell.qml | 32 ++++++++++++++ .../tutorials/helloworld/t1/tutorial1.qml | 22 ---------- .../declarative/tutorials/helloworld/t2/Cell.qml | 32 -------------- .../tutorials/helloworld/t2/tutorial2.qml | 31 ------------- .../declarative/tutorials/helloworld/t3/Cell.qml | 20 --------- .../tutorials/helloworld/t3/tutorial3.qml | 51 ---------------------- .../declarative/tutorials/helloworld/tutorial1.qml | 22 ++++++++++ .../declarative/tutorials/helloworld/tutorial2.qml | 31 +++++++++++++ .../declarative/tutorials/helloworld/tutorial3.qml | 51 ++++++++++++++++++++++ 12 files changed, 156 insertions(+), 176 deletions(-) create mode 100644 examples/declarative/tutorials/helloworld/Cell.qml delete mode 100644 examples/declarative/tutorials/helloworld/t1/tutorial1.qml delete mode 100644 examples/declarative/tutorials/helloworld/t2/Cell.qml delete mode 100644 examples/declarative/tutorials/helloworld/t2/tutorial2.qml delete mode 100644 examples/declarative/tutorials/helloworld/t3/Cell.qml delete mode 100644 examples/declarative/tutorials/helloworld/t3/tutorial3.qml create mode 100644 examples/declarative/tutorials/helloworld/tutorial1.qml create mode 100644 examples/declarative/tutorials/helloworld/tutorial2.qml create mode 100644 examples/declarative/tutorials/helloworld/tutorial3.qml diff --git a/doc/src/declarative/tutorial1.qdoc b/doc/src/declarative/tutorial1.qdoc index f46c59d..c9a1c5a 100644 --- a/doc/src/declarative/tutorial1.qdoc +++ b/doc/src/declarative/tutorial1.qdoc @@ -10,7 +10,7 @@ The picture below is a screenshot of this program. Here is the QML code for the application: -\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 0 +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 0 \section1 Walkthrough @@ -19,19 +19,20 @@ Here is the QML code for the application: First, we need to import the types that we need for this example. Most QML files will import the built-in QML types (like \l{Rectangle}, \l{Image}, ...) that come with Qt with: -\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 3 +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 3 \section2 Rectangle element -\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 1 +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 1 We declare a root element of type \l{Rectangle}. It is one of the basic building blocks you can use to create an application in QML. -We give it an \c{id} to be able to refer to it later. In this case, we call it \e page. We also set the \c width, \c height and \c color properties. +We give it an \c{id} to be able to refer to it later. In this case, we call it \e page. +We also set the \c width, \c height and \c color properties. The \l{Rectangle} element contains many other properties (such as \c x and \c y), but these are left at their default values. \section2 Text element -\snippet examples/declarative/tutorials/helloworld/t1/tutorial1.qml 2 +\snippet examples/declarative/tutorials/helloworld/tutorial1.qml 2 We add a \l Text element as a child of our root element that will display the text 'Hello world!'. @@ -44,13 +45,13 @@ In this case, we specify that our text element should be horizontally centered i \section2 Viewing the example -To view what you have created, run the qmlviewer (located in the \c bin directory) with your filename as the first argument. For example, to run the provided completed Tutorial 1 example from the install location, you would type: +To view what you have created, run the qmlviewer (located in the \c bin directory) with your filename as the first argument. +For example, to run the provided completed Tutorial 1 example from the install location, you would type: \code -bin/qmlviewer $QTDIR/examples/declarative/tutorials/helloworld/t1/tutorial1.qml +bin/qmlviewer $QTDIR/examples/declarative/tutorials/helloworld/tutorial1.qml \endcode [\l tutorial] [Next: \l tutorial2] */ - diff --git a/doc/src/declarative/tutorial2.qdoc b/doc/src/declarative/tutorial2.qdoc index 21b5ebd..a076a62 100644 --- a/doc/src/declarative/tutorial2.qdoc +++ b/doc/src/declarative/tutorial2.qdoc @@ -15,36 +15,36 @@ defined in its own QML file (for more details, see \l components). Here is the QML code for \c Cell.qml: -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 0 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 0 \section1 Walkthrough \section2 The Cell Component -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 1 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 1 The root element of our component is an \l Item with the \c id \e container. An \l Item is the most basic visual element in QML and is often used as a container for other elements. -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 4 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 4 We declare a \c color property. This property is accessible from \e outside our component, this allows us to instantiate the cells with different colors. This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{Properties}). -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 5 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 5 We want our component to also have a signal that we call \e clicked with a \e color parameter. We will use this signal to change the color of the text in the main QML file later. -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 2 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 2 Our cell component is basically a colored rectangle with the \c id \e rectangle. The \c anchors.fill property is a convenient way to set the size of an element. In this case the rectangle will have the same size as its parent (see \l{anchor-layout}{Anchor-based Layout}). -\snippet examples/declarative/tutorials/helloworld/t2/Cell.qml 3 +\snippet examples/declarative/tutorials/helloworld/Cell.qml 3 In order to change the color of the text when clicking on a cell, we create a \l MouseRegion element with the same size as its parent. @@ -56,11 +56,11 @@ When this signal is triggered we want to emit our own \e clicked signal with the In our main QML file, we use our \c Cell component to create the color picker: -\snippet examples/declarative/tutorials/helloworld/t2/tutorial2.qml 0 +\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 0 We create the color picker by putting 6 cells with different colors in a grid. -\snippet examples/declarative/tutorials/helloworld/t2/tutorial2.qml 1 +\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 1 When the \e clicked signal of our cell is triggered, we want to set the color of the text to the color passed as a parameter. We can react to any signal of our component through a property of the name \e 'onSignalName' (see \l{Signal Handlers}). diff --git a/doc/src/declarative/tutorial3.qdoc b/doc/src/declarative/tutorial3.qdoc index 21b7ae5..d766015 100644 --- a/doc/src/declarative/tutorial3.qdoc +++ b/doc/src/declarative/tutorial3.qdoc @@ -11,11 +11,11 @@ We want our text to move to the bottom of the screen, rotate and become red when Here is the QML code: -\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 0 +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 0 \section1 Walkthrough -\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 2 +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 2 First, we create a new \e down state for our text element. This state will be activated when the \l MouseRegion is pressed, and deactivated when it is released. @@ -24,7 +24,7 @@ The \e down state includes a set of property changes from our implicit \e {defau (the items as they were initially defined in the QML). Specifically, we set the \c y property of the text to \c 160, the rotation to \c 180 and the \c color to red. -\snippet examples/declarative/tutorials/helloworld/t3/tutorial3.qml 3 +\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 3 Because we don't want the text to appear at the bottom instantly but rather move smoothly, we add a transition between our two states. @@ -44,4 +44,3 @@ For more details on states and transitions, see \l {states-transitions}{States a [Previous: \l tutorial2] [\l tutorial] */ - diff --git a/examples/declarative/tutorials/helloworld/Cell.qml b/examples/declarative/tutorials/helloworld/Cell.qml new file mode 100644 index 0000000..ab6e565 --- /dev/null +++ b/examples/declarative/tutorials/helloworld/Cell.qml @@ -0,0 +1,32 @@ +//![0] +import Qt 4.6 + +//![1] +Item { + id: container +//![4] + property alias color: rectangle.color +//![4] +//![5] + signal clicked(string color) +//![5] + + width: 40; height: 25 +//![1] + +//![2] + Rectangle { + id: rectangle + border.color: "white" + anchors.fill: parent + } +//![2] + +//![3] + MouseRegion { + anchors.fill: parent + onClicked: container.clicked(container.color) + } +//![3] +} +//![0] diff --git a/examples/declarative/tutorials/helloworld/t1/tutorial1.qml b/examples/declarative/tutorials/helloworld/t1/tutorial1.qml deleted file mode 100644 index 93d3c34..0000000 --- a/examples/declarative/tutorials/helloworld/t1/tutorial1.qml +++ /dev/null @@ -1,22 +0,0 @@ -//![0] -//![3] -import Qt 4.6 -//![3] - -//![1] -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" -//![1] - -//![2] - Text { - id: helloText - text: "Hello world!" - font.pointSize: 24; font.bold: true - y: 30; anchors.horizontalCenter: page.horizontalCenter - } -//![2] -} -//![0] diff --git a/examples/declarative/tutorials/helloworld/t2/Cell.qml b/examples/declarative/tutorials/helloworld/t2/Cell.qml deleted file mode 100644 index ab6e565..0000000 --- a/examples/declarative/tutorials/helloworld/t2/Cell.qml +++ /dev/null @@ -1,32 +0,0 @@ -//![0] -import Qt 4.6 - -//![1] -Item { - id: container -//![4] - property alias color: rectangle.color -//![4] -//![5] - signal clicked(string color) -//![5] - - width: 40; height: 25 -//![1] - -//![2] - Rectangle { - id: rectangle - border.color: "white" - anchors.fill: parent - } -//![2] - -//![3] - MouseRegion { - anchors.fill: parent - onClicked: container.clicked(container.color) - } -//![3] -} -//![0] diff --git a/examples/declarative/tutorials/helloworld/t2/tutorial2.qml b/examples/declarative/tutorials/helloworld/t2/tutorial2.qml deleted file mode 100644 index 99889d7..0000000 --- a/examples/declarative/tutorials/helloworld/t2/tutorial2.qml +++ /dev/null @@ -1,31 +0,0 @@ -//![0] -import Qt 4.6 - -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" - - Text { - id: helloText - text: "Hello world!" - font.pointSize: 24; font.bold: true - y: 30; anchors.horizontalCenter: page.horizontalCenter - } - - Grid { - id: colorPicker - anchors.bottom: page.bottom - rows: 2; columns: 3; spacing: 3 - -//![1] - Cell { color: "red"; onClicked: helloText.color = color } -//![1] - Cell { color: "green"; onClicked: helloText.color = color } - Cell { color: "blue"; onClicked: helloText.color = color } - Cell { color: "yellow"; onClicked: helloText.color = color } - Cell { color: "steelblue"; onClicked: helloText.color = color } - Cell { color: "black"; onClicked: helloText.color = color } - } -} -//![0] diff --git a/examples/declarative/tutorials/helloworld/t3/Cell.qml b/examples/declarative/tutorials/helloworld/t3/Cell.qml deleted file mode 100644 index 578369d..0000000 --- a/examples/declarative/tutorials/helloworld/t3/Cell.qml +++ /dev/null @@ -1,20 +0,0 @@ -import Qt 4.6 - -Item { - id: container - property alias color: rectangle.color - signal clicked(string color) - - width: 40; height: 25 - - Rectangle { - id: rectangle - border.color: "white" - anchors.fill: parent - } - - MouseRegion { - anchors.fill: parent - onClicked: container.clicked(container.color) - } -} diff --git a/examples/declarative/tutorials/helloworld/t3/tutorial3.qml b/examples/declarative/tutorials/helloworld/t3/tutorial3.qml deleted file mode 100644 index d641eba..0000000 --- a/examples/declarative/tutorials/helloworld/t3/tutorial3.qml +++ /dev/null @@ -1,51 +0,0 @@ -//![0] -import Qt 4.6 - -Rectangle { - id: page - width: 500; height: 200 - color: "lightgray" - - Text { - id: helloText - text: "Hello world!" - font.pointSize: 24; font.bold: true - y: 30; anchors.horizontalCenter: page.horizontalCenter - transformOrigin: "Center" - -//![1] - MouseRegion { id: mouseRegion; anchors.fill: parent } -//![1] - -//![2] - states: State { - name: "down"; when: mouseRegion.pressed == true - PropertyChanges { target: helloText; y: 160; rotation: 180; color: "red" } - } -//![2] - -//![3] - transitions: Transition { - from: ""; to: "down"; reversible: true - ParallelAnimation { - NumberAnimation { properties: "y,rotation"; duration: 500; easing: "easeInOutQuad" } - ColorAnimation { property: "color"; duration: 500 } - } - } -//![3] - } - - Grid { - id: colorPicker - anchors.bottom: page.bottom - rows: 2; columns: 3; spacing: 3 - - Cell { color: "red"; onClicked: helloText.color = color } - Cell { color: "green"; onClicked: helloText.color = color } - Cell { color: "blue"; onClicked: helloText.color = color } - Cell { color: "yellow"; onClicked: helloText.color = color } - Cell { color: "steelblue"; onClicked: helloText.color = color } - Cell { color: "black"; onClicked: helloText.color = color } - } -} -//![0] diff --git a/examples/declarative/tutorials/helloworld/tutorial1.qml b/examples/declarative/tutorials/helloworld/tutorial1.qml new file mode 100644 index 0000000..93d3c34 --- /dev/null +++ b/examples/declarative/tutorials/helloworld/tutorial1.qml @@ -0,0 +1,22 @@ +//![0] +//![3] +import Qt 4.6 +//![3] + +//![1] +Rectangle { + id: page + width: 500; height: 200 + color: "lightgray" +//![1] + +//![2] + Text { + id: helloText + text: "Hello world!" + font.pointSize: 24; font.bold: true + y: 30; anchors.horizontalCenter: page.horizontalCenter + } +//![2] +} +//![0] diff --git a/examples/declarative/tutorials/helloworld/tutorial2.qml b/examples/declarative/tutorials/helloworld/tutorial2.qml new file mode 100644 index 0000000..99889d7 --- /dev/null +++ b/examples/declarative/tutorials/helloworld/tutorial2.qml @@ -0,0 +1,31 @@ +//![0] +import Qt 4.6 + +Rectangle { + id: page + width: 500; height: 200 + color: "lightgray" + + Text { + id: helloText + text: "Hello world!" + font.pointSize: 24; font.bold: true + y: 30; anchors.horizontalCenter: page.horizontalCenter + } + + Grid { + id: colorPicker + anchors.bottom: page.bottom + rows: 2; columns: 3; spacing: 3 + +//![1] + Cell { color: "red"; onClicked: helloText.color = color } +//![1] + Cell { color: "green"; onClicked: helloTex