83a5694dc2
Qt copyrights are now in The Qt Company, so we could update the source code headers accordingly. In the same go we should also fix the links to point to qt.io. Outdated header.LGPL removed (use header.LGPL21 instead) Old header.LGPL3 renamed to header.LGPL3-COMM to match actual licensing combination. New header.LGPL-COMM taken in the use file which were using old header.LGPL3 (src/plugins/platforms/android/extract.cpp) Added new header.LGPL3 containing Commercial + LGPLv3 + GPLv2 license combination Change-Id: I6f49b819a8a20cc4f88b794a8f6726d975e8ffbe Reviewed-by: Matti Paaso <matti.paaso@theqtcompany.com>
297 lines
11 KiB
Plaintext
297 lines
11 KiB
Plaintext
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2015 The Qt Company Ltd.
|
|
** Contact: http://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the documentation of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:FDL$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at http://www.qt.io/contact-us.
|
|
**
|
|
** GNU Free Documentation License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU Free
|
|
** Documentation License version 1.3 as published by the Free Software
|
|
** Foundation and appearing in the file included in the packaging of
|
|
** this file. Please review the following information to ensure
|
|
** the GNU Free Documentation License version 1.3 requirements
|
|
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
/*!
|
|
\example itemviews/stardelegate
|
|
\title Star Delegate Example
|
|
\ingroup examples-itemviews
|
|
\brief The Star Delegate example shows how to create a delegate that
|
|
can paint itself and that supports editing.
|
|
|
|
\image stardelegate.png The Star Delegate Example
|
|
|
|
When displaying data in a QListView, QTableView, or QTreeView,
|
|
the individual items are drawn by a
|
|
\l{Delegate Classes}{delegate}. Also, when the user starts
|
|
editing an item (e.g., by double-clicking the item), the delegate
|
|
provides an editor widget that is placed on top of the item while
|
|
editing takes place.
|
|
|
|
Delegates are subclasses of QAbstractItemDelegate. Qt provides
|
|
QItemDelegate, which inherits QAbstractItemDelegate and handles
|
|
the most common data types (notably \c int and QString). If we
|
|
need to support custom data types, or want to customize the
|
|
rendering or the editing for existing data types, we can subclass
|
|
QAbstractItemDelegate or QItemDelegate. See \l{Delegate Classes}
|
|
for more information about delegates, and \l{Model/View
|
|
Programming} if you need a high-level introduction to Qt's
|
|
model/view architecture (including delegates).
|
|
|
|
In this example, we will see how to implement a custom delegate
|
|
to render and edit a "star rating" data type, which can store
|
|
values such as "1 out of 5 stars".
|
|
|
|
The example consists of the following classes:
|
|
|
|
\list
|
|
\li \c StarRating is the custom data type. It stores a rating
|
|
expressed as stars, such as "2 out of 5 stars" or "5 out of
|
|
6 stars".
|
|
|
|
\li \c StarDelegate inherits QItemDelegate and provides support
|
|
for \c StarRating (in addition to the data types already
|
|
handled by QItemDelegate).
|
|
|
|
\li \c StarEditor inherits QWidget and is used by \c StarDelegate
|
|
to let the user edit a star rating using the mouse.
|
|
\endlist
|
|
|
|
To show the \c StarDelegate in action, we will fill a
|
|
QTableWidget with some data and install the delegate on it.
|
|
|
|
\section1 StarDelegate Class Definition
|
|
|
|
Here's the definition of the \c StarDelegate class:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.h 0
|
|
|
|
All public functions are reimplemented virtual functions from
|
|
QItemDelegate to provide custom rendering and editing.
|
|
|
|
\section1 StarDelegate Class Implementation
|
|
|
|
The \l{QAbstractItemDelegate::}{paint()} function is
|
|
reimplemented from QItemDelegate and is called whenever the view
|
|
needs to repaint an item:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 0
|
|
|
|
The function is invoked once for each item, represented by a
|
|
QModelIndex object from the model. If the data stored in the item
|
|
is a \c StarRating, we paint it ourselves; otherwise, we let
|
|
QItemDelegate paint it for us. This ensures that the \c
|
|
StarDelegate can handle the most common data types.
|
|
|
|
In the case where the item is a \c StarRating, we draw the
|
|
background if the item is selected, and we draw the item using \c
|
|
StarRating::paint(), which we will review later.
|
|
|
|
\c{StartRating}s can be stored in a QVariant thanks to the
|
|
Q_DECLARE_METATYPE() macro appearing in \c starrating.h. More on
|
|
this later.
|
|
|
|
The \l{QAbstractItemDelegate::}{createEditor()} function is
|
|
called when the user starts editing an item:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 2
|
|
|
|
If the item is a \c StarRating, we create a \c StarEditor and
|
|
connect its \c editingFinished() signal to our \c
|
|
commitAndCloseEditor() slot, so we can update the model when the
|
|
editor closes.
|
|
|
|
Here's the implementation of \c commitAndCloseEditor():
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 5
|
|
|
|
When the user is done editing, we emit
|
|
\l{QAbstractItemDelegate::}{commitData()} and
|
|
\l{QAbstractItemDelegate::}{closeEditor()} (both declared in
|
|
QAbstractItemDelegate), to tell the model that there is edited
|
|
data and to inform the view that the editor is no longer needed.
|
|
|
|
The \l{QAbstractItemDelegate::}{setEditorData()} function is
|
|
called when an editor is created to initialize it with data
|
|
from the model:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 3
|
|
|
|
We simply call \c setStarRating() on the editor.
|
|
|
|
The \l{QAbstractItemDelegate::}{setModelData()} function is
|
|
called when editing is finished, to commit data from the editor
|
|
to the model:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 4
|
|
|
|
The \c sizeHint() function returns an item's preferred size:
|
|
|
|
\snippet itemviews/stardelegate/stardelegate.cpp 1
|
|
|
|
We simply forward the call to \c StarRating.
|
|
|
|
\section1 StarEditor Class Definition
|
|
|
|
The \c StarEditor class was used when implementing \c
|
|
StarDelegate. Here's the class definition:
|
|
|
|
\snippet itemviews/stardelegate/stareditor.h 0
|
|
|
|
The class lets the user edit a \c StarRating by moving the mouse
|
|
over the editor. It emits the \c editingFinished() signal when
|
|
the user clicks on the editor.
|
|
|
|
The protected functions are reimplemented from QWidget to handle
|
|
mouse and paint events. The private function \c starAtPosition()
|
|
is a helper function that returns the number of the star under
|
|
the mouse pointer.
|
|
|
|
\section1 StarEditor Class Implementation
|
|
|
|
Let's start with the constructor:
|
|
|
|
\snippet itemviews/stardelegate/stareditor.cpp 0
|
|
|
|
We enable \l{QWidget::setMouseTracking()}{mouse tracking} on the
|
|
widget so we can follow the cursor even when the user doesn't
|
|
hold down any mouse button. We also turn on QWidget's
|
|
\l{QWidget::autoFillBackground}{auto-fill background} feature to
|
|
obtain an opaque background. (Without the call, the view's
|
|
background would shine through the editor.)
|
|
|
|
The \l{QWidget::}{paintEvent()} function is reimplemented from
|
|
QWidget:
|
|
|
|
\snippet itemviews/stardelegate/stareditor.cpp 1
|
|
|
|
We simply call \c StarRating::paint() to draw the stars, just
|
|
like we did when implementing \c StarDelegate.
|
|
|
|
\snippet itemviews/stardelegate/stareditor.cpp 2
|
|
|
|
In the mouse event handler, we call \c setStarCount() on the
|
|
private data member \c myStarRating to reflect the current cursor
|
|
position, and we call QWidget::update() to force a repaint.
|
|
|
|
\snippet itemviews/stardelegate/stareditor.cpp 3
|
|
|
|
When the user releases a mouse button, we simply emit the \c
|
|
editingFinished() signal.
|
|
|
|
\snippet itemviews/stardelegate/stareditor.cpp 4
|
|
|
|
The \c starAtPosition() function uses basic linear algebra to
|
|
find out which star is under the cursor.
|
|
|
|
\section1 StarRating Class Definition
|
|
|
|
\snippet itemviews/stardelegate/starrating.h 0
|
|
\codeline
|
|
\snippet itemviews/stardelegate/starrating.h 1
|
|
|
|
The \c StarRating class represents a rating as a number of stars.
|
|
In addition to holding the data, it is also capable of painting
|
|
the stars on a QPaintDevice, which in this example is either a
|
|
view or an editor. The \c myStarCount member variable stores the
|
|
current rating, and \c myMaxStarCount stores the highest possible
|
|
rating (typically 5).
|
|
|
|
The Q_DECLARE_METATYPE() macro makes the type \c StarRating known
|
|
to QVariant, making it possible to store \c StarRating values in
|
|
QVariant.
|
|
|
|
\section1 StarRating Class Implementation
|
|
|
|
The constructor initializes \c myStarCount and \c myMaxStarCount,
|
|
and sets up the polygons used to draw stars and diamonds:
|
|
|
|
\snippet itemviews/stardelegate/starrating.cpp 0
|
|
|
|
The \c paint() function paints the stars in this \c StarRating
|
|
object on a paint device:
|
|
|
|
\snippet itemviews/stardelegate/starrating.cpp 2
|
|
|
|
We first set the pen and brush we will use for painting. The \c
|
|
mode parameter can be either \c Editable or \c ReadOnly. If \c
|
|
mode is editable, we use the \l{QPalette::}{Highlight} color
|
|
instead of the \l{QPalette::}{Foreground} color to draw the
|
|
stars.
|
|
|
|
Then we draw the stars. If we are in \c Edit mode, we paint
|
|
diamonds in place of stars if the rating is less than the highest
|
|
rating.
|
|
|
|
The \c sizeHint() function returns the preferred size for an area
|
|
to paint the stars on:
|
|
|
|
\snippet itemviews/stardelegate/starrating.cpp 1
|
|
|
|
The preferred size is just enough to paint the maximum number of
|
|
stars. The function is called by both \c StarDelegate::sizeHint()
|
|
and \c StarEditor::sizeHint().
|
|
|
|
\section1 The \c main() Function
|
|
|
|
Here's the program's \c main() function:
|
|
|
|
\snippet itemviews/stardelegate/main.cpp 5
|
|
|
|
The \c main() function creates a QTableWidget and sets a \c
|
|
StarDelegate on it. \l{QAbstractItemView::}{DoubleClicked} and
|
|
\l{QAbstractItemView::}{SelectedClicked} are set as
|
|
\l{QAbstractItemView::editTriggers()}{edit triggers}, so that the
|
|
editor is opened with a single click when the star rating item is
|
|
selected.
|
|
|
|
The \c populateTableWidget() function fills the QTableWidget with
|
|
data:
|
|
|
|
\snippet itemviews/stardelegate/main.cpp 0
|
|
\snippet itemviews/stardelegate/main.cpp 1
|
|
\dots
|
|
\snippet itemviews/stardelegate/main.cpp 2
|
|
\snippet itemviews/stardelegate/main.cpp 3
|
|
\codeline
|
|
\snippet itemviews/stardelegate/main.cpp 4
|
|
|
|
Notice the call to qVariantFromValue to convert a \c
|
|
StarRating to a QVariant.
|
|
|
|
\section1 Possible Extensions and Suggestions
|
|
|
|
There are many ways to customize Qt's \l{Model/View
|
|
Programming}{model/view framework}. The approach used in this
|
|
example is appropriate for most custom delegates and editors.
|
|
Examples of possibilities not used by the star delegate and star
|
|
editor are:
|
|
|
|
\list
|
|
\li It is possible to open editors programmatically by calling
|
|
QAbstractItemView::edit(), instead of relying on edit
|
|
triggers. This could be use to support other edit triggers
|
|
than those offered by the QAbstractItemView::EditTrigger enum.
|
|
For example, in the Star Delegate example, hovering over an
|
|
item with the mouse might make sense as a way to pop up an
|
|
editor.
|
|
|
|
\li By reimplementing QAbstractItemDelegate::editorEvent(), it is
|
|
possible to implement the editor directly in the delegate,
|
|
instead of creating a separate QWidget subclass.
|
|
\endlist
|
|
*/
|