diff options
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/doc/snippets/qml/regexp.qml | 46 | ||||
-rw-r--r-- | src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc | 59 | ||||
-rw-r--r-- | src/quick/doc/src/concepts/positioning/layouts.qdoc | 3 | ||||
-rw-r--r-- | src/quick/items/qquickgridview.cpp | 4 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 8 | ||||
-rw-r--r-- | src/quick/items/qquickitemview_p_p.h | 9 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 4 | ||||
-rw-r--r-- | src/quick/items/qquickrendercontrol.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 12 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 10 | ||||
-rw-r--r-- | src/quick/util/qquickvalidator.cpp | 19 |
15 files changed, 153 insertions, 30 deletions
diff --git a/src/quick/doc/snippets/qml/regexp.qml b/src/quick/doc/snippets/qml/regexp.qml new file mode 100644 index 0000000000..c30336d418 --- /dev/null +++ b/src/quick/doc/snippets/qml/regexp.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 +//![0] +TextInput { + id: hexNumber + validator: RegExpValidator { regExp: /[0-9A-F]+/ } +} +//![0] diff --git a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc index 324fc9750f..47dcd6d98c 100644 --- a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc +++ b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc @@ -87,6 +87,7 @@ To visualize data, bind the view's \c model property to a model and the The club may decorate the members list by binding visual objects to the \c header and \c footer properties. The visual object may be defined inline, in another file, or in a \l {Component} type. + \snippet qml/listview-decorations.qml decorations \image listview-decorations.png @@ -102,7 +103,6 @@ To visualize data, bind the view's \c model property to a model and the will always ensure that the \c currentIndex is within the highlight range specified. - \section2 ListView Sections \l {ListView} contents may be grouped into \e sections, where related list @@ -195,7 +195,7 @@ To visualize data, bind the view's \c model property to a model and the Positioning of items from a model can be achieved using a \l{Repeater}. - \section2 ListModel + \section2 List Model ListModel is a simple hierarchy of types specified in QML. The available roles are specified by the \l ListElement properties. @@ -222,7 +222,7 @@ To visualize data, bind the view's \c model property to a model and the using the model. To reset the roles available in the model, call ListModel::clear(). - \section2 XmlListModel + \section2 XML Model XmlListModel allows construction of a model from an XML data source. The roles are specified via the \l XmlRole type. The type needs to be imported. @@ -244,23 +244,44 @@ To visualize data, bind the view's \c model property to a model and the } \endqml + The \c query property specifies that the XmlListModel generates a model item + for each \c <item> in the XML document. + The \l{Qt Quick Demo - RSS News}{RSS News demo} shows how XmlListModel can be used to display an RSS feed. - \section2 VisualItemModel + \section2 Object Model + + ObjectModel contains the visual items to be used in a view. When an ObjectModel + is used in a view, the view does not require a delegate because the ObjectModel + already contains the visual delegate (items). - VisualItemModel allows QML items to be provided as a model. + The example below places three colored rectangles in a ListView. - This model contains both the data and delegate; the child items of a - VisualItemModel provide the contents of the delegate. The model - does not provide any roles. + \code + import QtQuick 2.0 + import QtQml.Models 2.1 + + Rectangle { + ObjectModel { + id: itemModel + Rectangle { height: 30; width: 80; color: "red" } + Rectangle { height: 30; width: 80; color: "green" } + Rectangle { height: 30; width: 80; color: "blue" } + } - \snippet qml/models/visual-model-and-view.qml visual model and view + ListView { + anchors.fill: parent + model: itemModel + } + } + \endcode - Note that in the above example there is no delegate required. - The items of the model itself provide the visual types that - will be positioned by the view. + \note VisualItemModel can also be used, but it is only provided for compatibility + reasons. VisualItemModel allows a QML item to be provided as a model. This model + contains both the data and delegate; the child items of a VisualItemModel + provide the contents of the delegate. The model does not provide any roles. \section2 Integers as Models @@ -357,8 +378,18 @@ rectangles for the Grid item to position in a 5 by 5 arrangement. The number of items created by a Repeater is held by its \l{Repeater::}{count} property. It is not possible to set this property to determine the number of items to be created. Instead, as in the above example, we use an integer as -the model. This is explained in the \l{qtquick-modelviewsdata-modelview.html#integers-as-models}{QML Data Models} -document. +the model. + +For more details, see the \l{qtquick-modelviewsdata-modelview.html#integers-as-models}{QML Data Models} document. + +If the model is a string list, the delegate is also exposed to a read-only +\c modelData property that holds the string. For example: + +\table + \row + \li \snippet qml/repeaters/repeater.qml modeldata + \li \image repeater-modeldata.png +\endtable It is also possible to use a delegate as the template for the items created by a Repeater. This is specified using the \l{Repeater::}{delegate} property. diff --git a/src/quick/doc/src/concepts/positioning/layouts.qdoc b/src/quick/doc/src/concepts/positioning/layouts.qdoc index 47ed2563f8..3824d17559 100644 --- a/src/quick/doc/src/concepts/positioning/layouts.qdoc +++ b/src/quick/doc/src/concepts/positioning/layouts.qdoc @@ -133,6 +133,5 @@ control of spacing between items and between lines of items. There are several other ways to position items in a user interface. In addition to the basic technique of specifying their coordinates directly, they can be positioned relative to other items with \l{anchor-layout}{anchors}, or used -with \l{QML Data Models} such as -\l{QML Data Models#VisualItemModel}{VisualItemModel}. +with \l{QML Data Models} such as \l{QML Data Models#Object Model}{Object Model}. */ diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index fd78c46a16..c570b95a21 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -495,9 +495,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal // We've jumped more than a page. Estimate which items are now // visible and fill from there. int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns; - for (FxViewItem *item : qAsConst(visibleItems)) - releaseItem(item); - visibleItems.clear(); + releaseVisibleItems(); modelIndex += count; if (modelIndex >= model->count()) modelIndex = model->count() - 1; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 555db03962..084b1f197a 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -380,9 +380,7 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate) int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { - for (FxViewItem *item : qAsConst(d->visibleItems)) - d->releaseItem(item); - d->visibleItems.clear(); + d->releaseVisibleItems(); d->releaseItem(d->currentItem); d->currentItem = 0; d->updateSectionCriteria(); @@ -1743,9 +1741,7 @@ void QQuickItemViewPrivate::clear() currentChanges.reset(); timeline.clear(); - for (FxViewItem *item : qAsConst(visibleItems)) - releaseItem(item); - visibleItems.clear(); + releaseVisibleItems(); visibleIndex = 0; for (FxViewItem *item : qAsConst(releasePendingTransition)) { diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 3087682ac7..b6353246e8 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -269,6 +269,15 @@ public: q->polish(); } + void releaseVisibleItems() { + // make a copy and clear the visibleItems first to avoid destroyed + // items being accessed during the loop (QTBUG-61294) + const QList<FxViewItem *> oldVisible = visibleItems; + visibleItems.clear(); + for (FxViewItem *item : oldVisible) + releaseItem(item); + } + QPointer<QQmlInstanceModel> model; QVariant modelVariant; int itemCount; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index f739115e6b..18f9b8512d 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -660,9 +660,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal int newModelIdx = qBound(0, modelIndex + count, model->count()); count = newModelIdx - modelIndex; if (count) { - for (FxViewItem *item : qAsConst(visibleItems)) - releaseItem(item); - visibleItems.clear(); + releaseVisibleItems(); modelIndex = newModelIdx; visibleIndex = modelIndex; visiblePos = itemEnd + count * (averageSize + spacing); diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index f2828bbedd..7e995936af 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -284,6 +284,7 @@ bool QQuickRenderControl::sync() QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); cd->syncSceneGraph(); + d->rc->endSync(); // TODO: find out if the sync actually caused a scenegraph update. return true; @@ -383,6 +384,7 @@ QImage QQuickRenderControl::grab() QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); cd->polishItems(); cd->syncSceneGraph(); + d->rc->endSync(); render(); grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); if (QQuickRenderControl::renderWindowFor(d->window)) { @@ -402,6 +404,7 @@ QImage QQuickRenderControl::grab() softwareRenderer->markDirty(); cd->polishItems(); cd->syncSceneGraph(); + d->rc->endSync(); render(); softwareRenderer->setCurrentPaintDevice(prevDev); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index d30f1c3f78..433c5b25b1 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -432,10 +432,8 @@ void QQuickWindowPrivate::syncSceneGraph() emit q->afterSynchronizing(); runAndClearJobs(&afterSynchronizingJobs); - context->endSync(); } - void QQuickWindowPrivate::renderSceneGraph(const QSize &size) { QML_MEMORY_SCOPE_STRING("SceneGraph"); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index 962db20cbc..3f0d1383b9 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -149,6 +149,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) emit window->afterAnimating(); cd->syncSceneGraph(); + rc->endSync(); if (profileFrames) syncTime = renderTimer.nsecsElapsed(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index 71db35377e..19f16a79fb 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -330,6 +330,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e) softwareRenderer->setBackingStore(backingStore); rc->initialize(nullptr); wd->syncSceneGraph(); + rc->endSync(); wd->renderSceneGraph(wme->window->size()); *wme->image = backingStore->handle()->toImage(); } @@ -443,6 +444,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose) rc->initialize(nullptr); wd->syncSceneGraph(); + rc->endSync(); if (!hadRenderer && wd->renderer) { qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - created renderer"); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index c27700cf84..bc65dc1bc3 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -380,6 +380,16 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) bool alsoSwap = data.updatePending; data.updatePending = false; + bool lastDirtyWindow = true; + auto i = m_windows.constBegin(); + while (i != m_windows.constEnd()) { + if (i.value().updatePending) { + lastDirtyWindow = false; + break; + } + i++; + } + if (!current) return; @@ -407,6 +417,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) emit window->afterAnimating(); cd->syncSceneGraph(); + if (lastDirtyWindow) + rc->endSync(); if (profileFrames) syncTime = renderTimer.nsecsElapsed(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 2364fb714c..3a8e673c0d 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -425,6 +425,7 @@ bool QSGRenderThread::event(QEvent *e) qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph"; QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window); d->syncSceneGraph(); + sgrc->endSync(); qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph"; QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size()); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index e16f7ea966..e10e52d95e 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -445,6 +445,14 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) } } + bool lastDirtyWindow = true; + for (int i=0; i<m_windows.size(); ++i) { + if ( m_windows[i].pendingUpdate) { + lastDirtyWindow = false; + break; + } + } + d->flushFrameSynchronousEvents(); // Event delivery or processing has caused the window to stop rendering. if (!windowData(window)) @@ -464,6 +472,8 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) RLDEBUG(" - syncing"); d->syncSceneGraph(); + if (lastDirtyWindow) + m_rc->endSync(); QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced, QQuickProfiler::SceneGraphRenderLoopSync); diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp index a05117bd06..c3ce149dcf 100644 --- a/src/quick/util/qquickvalidator.cpp +++ b/src/quick/util/qquickvalidator.cpp @@ -219,6 +219,25 @@ void QQuickDoubleValidator::resetLocaleName() matching "a". By default, this property contains a regular expression with the pattern .* that matches any string. + + Below you can find an example of a \l TextInput object with a RegExpValidator specified: + + \snippet qml/regexp.qml 0 + + Some more examples of regular expressions: + + \list + \li A list of numbers with one to three positions separated by a comma: + \badcode + /\d{1,3}(?:,\d{1,3})+$/ + \endcode + + \li An amount consisting of up to 3 numbers before the decimal point, and + 1 to 2 after the decimal point: + \badcode + /(\d{1,3})([.,]\d{1,2})?$/ + \endcode + \endlist */ #endif // validator |