Turn SpinBox Delegate example into snippets
The essence of the example was already fully quoted in the model/view documentation. Move the code into a snippet source, and update the screenshot. Fixes: QTBUG-119976 Pick-to: 6.7 6.6 Change-Id: Id2f10bb26a650419969bbfa9b76cb74babd3319e Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
This commit is contained in:
parent
7996a3fc7f
commit
99eaae4323
@ -1,118 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example itemviews/spinboxdelegate
|
||||
\title Spin Box Delegate Example
|
||||
\examplecategory {User Interface Components}
|
||||
\ingroup examples-itemviews
|
||||
\brief The Spin Box Delegate example shows how to create an editor for a custom delegate in
|
||||
the model/view framework by reusing a standard Qt editor widget.
|
||||
|
||||
The model/view framework provides a standard delegate that is used by default
|
||||
with the standard view classes. For most purposes, the selection of editor
|
||||
widgets available through this delegate is sufficient for editing text, boolean
|
||||
values, and other simple data types. However, for specific data types, it is
|
||||
sometimes necessary to use a custom delegate to either display the data in a
|
||||
specific way, or allow the user to edit it with a custom control.
|
||||
|
||||
\image spinboxdelegate-example.png
|
||||
|
||||
This concepts behind this example are covered in the
|
||||
\l{Model/View Programming#Delegate Classes}{Delegate Classes} chapter
|
||||
of the \l{Model/View Programming} overview.
|
||||
|
||||
\section1 SpinBoxDelegate Class Definition
|
||||
|
||||
The definition of the delegate is as follows:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.h 0
|
||||
|
||||
The delegate class declares only those functions that are needed to
|
||||
create an editor widget, display it at the correct location in a view,
|
||||
and communicate with a model. Custom delegates can also provide their
|
||||
own painting code by reimplementing the \c paintEvent() function.
|
||||
Furthermore it is also possible to reuse (and avoid deleting) the editor
|
||||
widget by reimplementing the \a destroyEditor() function. A reused widget
|
||||
could be a mutable member created in the constructor and deleted in
|
||||
the destructor.
|
||||
|
||||
\section1 SpinBoxDelegate Class Implementation
|
||||
|
||||
Delegates are often stateless. The constructor only needs to
|
||||
call the base class's constructor with the parent QObject as its
|
||||
argument:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 0
|
||||
|
||||
Since the delegate is a subclass of QStyledItemDelegate, the data it retrieves
|
||||
from the model is displayed in a default style, and we do not need to
|
||||
provide a custom \c paintEvent().
|
||||
|
||||
The \c createEditor() function returns an editor widget, in this case a
|
||||
spin box that restricts values from the model to integers from 0 to 100
|
||||
inclusive.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 1
|
||||
|
||||
We install an event filter on the spin box to ensure that it behaves in
|
||||
a way that is consistent with other delegates. The implementation for
|
||||
the event filter is provided by the base class.
|
||||
|
||||
The \c setEditorData() function reads data from the model, converts it
|
||||
to an integer value, and writes it to the editor widget.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 2
|
||||
|
||||
Since the view treats delegates as ordinary QWidget instances, we have
|
||||
to use a static cast before we can set the value in the spin box.
|
||||
|
||||
The \c setModelData() function reads the contents of the spin box, and
|
||||
writes it to the model.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 3
|
||||
|
||||
We call \l{QSpinBox::interpretText()}{interpretText()} to make sure that
|
||||
we obtain the most up-to-date value in the spin box.
|
||||
|
||||
The \c updateEditorGeometry() function updates the editor widget's
|
||||
geometry using the information supplied in the style option. This is the
|
||||
minimum that the delegate must do in this case.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 4
|
||||
|
||||
More complex editor widgets may divide the rectangle available in
|
||||
\c{option.rect} between different child widgets if required.
|
||||
|
||||
\section1 The Main Function
|
||||
|
||||
This example is written in a slightly different way to many of the
|
||||
other examples supplied with Qt. To demonstrate the use of a custom
|
||||
editor widget in a standard view, it is necessary to set up a model
|
||||
containing some arbitrary data and a view to display it.
|
||||
|
||||
We set up the application in the normal way, construct a standard item
|
||||
model to hold some data, set up a table view to use the data in the
|
||||
model, and construct a custom delegate to use for editing:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/main.cpp 0
|
||||
|
||||
The table view is informed about the delegate, and will use it to
|
||||
display each of the items. Since the delegate is a subclass of
|
||||
QStyledItemDelegate, each cell in the table will be rendered using standard
|
||||
painting operations.
|
||||
|
||||
We insert some arbitrary data into the model for demonstration purposes:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/main.cpp 1
|
||||
\snippet itemviews/spinboxdelegate/main.cpp 2
|
||||
|
||||
Finally, the table view is displayed with a window title, and we start
|
||||
the application's event loop:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/main.cpp 3
|
||||
|
||||
Each of the cells in the table can now be edited in the usual way, but
|
||||
the spin box ensures that the data returned to the model is always
|
||||
constrained by the values allowed by the spin box delegate.
|
||||
*/
|
@ -9,6 +9,5 @@ qt_internal_add_example(customsortfiltermodel)
|
||||
qt_internal_add_example(editabletreemodel)
|
||||
qt_internal_add_example(fetchmore)
|
||||
qt_internal_add_example(frozencolumn)
|
||||
qt_internal_add_example(spinboxdelegate)
|
||||
qt_internal_add_example(spreadsheet)
|
||||
qt_internal_add_example(stardelegate)
|
||||
|
@ -8,6 +8,5 @@ SUBDIRS = addressbook \
|
||||
fetchmore \
|
||||
frozencolumn \
|
||||
simpletreemodel \
|
||||
spinboxdelegate \
|
||||
spreadsheet \
|
||||
stardelegate
|
||||
|
@ -1,37 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(spinboxdelegate LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/spinboxdelegate")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(spinboxdelegate
|
||||
delegate.cpp delegate.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(spinboxdelegate PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(spinboxdelegate PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS spinboxdelegate
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -1,29 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DELEGATE_H
|
||||
#define DELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
//! [0]
|
||||
class SpinBoxDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SpinBoxDelegate(QObject *parent = nullptr);
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
@ -1,48 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
/*
|
||||
main.cpp
|
||||
|
||||
A simple example that shows how a view can use a custom delegate to edit
|
||||
data obtained from a model.
|
||||
*/
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QHeaderView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
|
||||
//! [0]
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QStandardItemModel model(4, 2);
|
||||
QTableView tableView;
|
||||
tableView.setModel(&model);
|
||||
|
||||
SpinBoxDelegate delegate;
|
||||
tableView.setItemDelegate(&delegate);
|
||||
//! [0]
|
||||
|
||||
tableView.horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
//! [1]
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
for (int column = 0; column < 2; ++column) {
|
||||
QModelIndex index = model.index(row, column, QModelIndex());
|
||||
model.setData(index, QVariant((row + 1) * (column + 1)));
|
||||
}
|
||||
//! [1] //! [2]
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
|
||||
tableView.show();
|
||||
return app.exec();
|
||||
}
|
||||
//! [3]
|
@ -1,10 +0,0 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(tableview))
|
||||
|
||||
HEADERS = delegate.h
|
||||
SOURCES = delegate.cpp \
|
||||
main.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/spinboxdelegate
|
||||
INSTALLS += target
|
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB |
BIN
src/widgets/doc/images/spinboxdelegate-example.webp
Normal file
BIN
src/widgets/doc/images/spinboxdelegate-example.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
12
src/widgets/doc/snippets/qitemdelegate/CMakeLists.txt
Normal file
12
src/widgets/doc/snippets/qitemdelegate/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (C) 2023 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_library(widgets_qitemdelegate_snippets OBJECT
|
||||
spinbox-delegate.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(widgets_qitemdelegate_snippets PRIVATE
|
||||
Qt::Core
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -1,25 +1,37 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
/*
|
||||
delegate.cpp
|
||||
|
||||
A delegate that allows the user to change integer values from the model
|
||||
using a spin box widget.
|
||||
*/
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QSpinBox>
|
||||
|
||||
//! [0]
|
||||
//! [declaration]
|
||||
class SpinBoxDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SpinBoxDelegate(QObject *parent = nullptr);
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
};
|
||||
//! [declaration]
|
||||
|
||||
//! [constructor]
|
||||
SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
//! [0]
|
||||
//! [constructor]
|
||||
|
||||
//! [1]
|
||||
//! [createEditor]
|
||||
QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &/* option */,
|
||||
const QModelIndex &/* index */) const
|
||||
@ -31,9 +43,9 @@ QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
|
||||
|
||||
return editor;
|
||||
}
|
||||
//! [1]
|
||||
//! [createEditor]
|
||||
|
||||
//! [2]
|
||||
//! [setEditorData]
|
||||
void SpinBoxDelegate::setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
@ -42,9 +54,9 @@ void SpinBoxDelegate::setEditorData(QWidget *editor,
|
||||
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
|
||||
spinBox->setValue(value);
|
||||
}
|
||||
//! [2]
|
||||
//! [setEditorData]
|
||||
|
||||
//! [3]
|
||||
//! [setModelData]
|
||||
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
@ -54,13 +66,14 @@ void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
|
||||
model->setData(index, value, Qt::EditRole);
|
||||
}
|
||||
//! [3]
|
||||
//! [setModelData]
|
||||
|
||||
//! [4]
|
||||
//! [updateEditorGeometry]
|
||||
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &/* index */) const
|
||||
{
|
||||
editor->setGeometry(option.rect);
|
||||
}
|
||||
//! [4]
|
||||
//! [updateEditorGeometry]
|
||||
|
@ -686,9 +686,8 @@
|
||||
implementations of these functions.
|
||||
|
||||
Editors for delegates can be implemented either by using widgets to manage
|
||||
the editing process or by handling events directly.
|
||||
The first approach is covered later in this section, and it is also
|
||||
shown in the \l{Spin Box Delegate Example}{Spin Box Delegate} example.
|
||||
the editing process or by handling events directly. The first approach is
|
||||
covered later in this section.
|
||||
|
||||
\section2 Using an existing delegate
|
||||
|
||||
@ -718,13 +717,15 @@
|
||||
data entry. We construct a table view to display the contents of
|
||||
the model, and this will use the custom delegate for editing.
|
||||
|
||||
\image spinboxdelegate-example.png
|
||||
\image spinboxdelegate-example.webp
|
||||
|
||||
We subclass the delegate from \l QStyledItemDelegate because we do not want
|
||||
to write custom display functions. However, we must still provide
|
||||
functions to manage the editor widget:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.h 0
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp declaration
|
||||
\codeline
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp constructor
|
||||
|
||||
Note that no editor widgets are set up when the delegate is
|
||||
constructed. We only construct an editor widget when it is needed.
|
||||
@ -738,7 +739,7 @@
|
||||
supplied with everything that the delegate needs to be able to set up
|
||||
a suitable widget:
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 1
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp createEditor
|
||||
|
||||
Note that we do not need to keep a pointer to the editor widget because
|
||||
the view takes responsibility for destroying it when it is no longer
|
||||
@ -762,7 +763,7 @@
|
||||
\l{Qt::ItemDataRole}{display role}, and set the value in the
|
||||
spin box accordingly.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 2
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp setEditorData
|
||||
|
||||
In this example, we know that the editor widget is a spin box, but we
|
||||
could have provided different editors for different types of data in
|
||||
@ -775,7 +776,7 @@
|
||||
asks the delegate to store the edited value in the model by calling the
|
||||
\l{QAbstractItemDelegate::setModelData()}{setModelData()} function.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 3
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp setModelData
|
||||
|
||||
Since the view manages the editor widgets for the delegate, we only
|
||||
need to update the model with the contents of the editor supplied.
|
||||
@ -786,8 +787,8 @@
|
||||
finished editing by emitting the
|
||||
\l{QAbstractItemDelegate::closeEditor()}{closeEditor()} signal.
|
||||
The view ensures that the editor widget is closed and destroyed. In
|
||||
this example, we only provide simple editing facilities, so we need
|
||||
never emit this signal.
|
||||
this example, we only provide simple editing facilities, so we never
|
||||
need to emit this signal.
|
||||
|
||||
All the operations on data are performed through the interface
|
||||
provided by \l QAbstractItemModel. This makes the delegate mostly
|
||||
@ -806,7 +807,7 @@
|
||||
the view provides all the necessary geometry information inside a
|
||||
\l{QStyleOptionViewItem}{view option} object.
|
||||
|
||||
\snippet itemviews/spinboxdelegate/delegate.cpp 4
|
||||
\snippet qitemdelegate/spinbox-delegate.cpp updateEditorGeometry
|
||||
|
||||
In this case, we just use the geometry information provided by the
|
||||
view option in the item rectangle. A delegate that renders items with
|
||||
@ -2308,7 +2309,6 @@
|
||||
\section1 Related Examples
|
||||
|
||||
\list
|
||||
\li \l{itemviews/spinboxdelegate}{Spin Box Delegate}
|
||||
\li \l{itemviews/simpletreemodel}{Simple Tree Model}
|
||||
\endlist
|
||||
*/
|
||||
|
@ -534,7 +534,7 @@
|
||||
Other references to delegates in Qt Documentation:
|
||||
|
||||
\list
|
||||
\li \l{Spin Box Delegate Example}
|
||||
\li \l{Delegate Classes}
|
||||
\li \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
|
||||
\li \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
|
||||
\li \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
|
||||
@ -826,11 +826,6 @@
|
||||
\li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
|
||||
\li QStandardItemModel
|
||||
\li Basic QDataWidgetMapper usage
|
||||
\row
|
||||
\li Spin Box Delegate
|
||||
\li QTableView
|
||||
\li QStandardItemModel
|
||||
\li Custom delegate that uses a spin box as a cell editor
|
||||
\row
|
||||
\li Spreadsheet
|
||||
\li {2, 1} QTableView
|
||||
|
@ -266,8 +266,8 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
|
||||
made available to delegates with the default item editor
|
||||
factory. This way, there is no need to subclass QItemDelegate. An
|
||||
alternative is to reimplement createEditor(), setEditorData(),
|
||||
setModelData(), and updateEditorGeometry(). This process is
|
||||
described in the \l{Spin Box Delegate Example}.
|
||||
setModelData(), and updateEditorGeometry(). This process is described
|
||||
in the \l{A simple delegate}{Model/View Programming overview documentation}.
|
||||
|
||||
\section1 QStyledItemDelegate vs. QItemDelegate
|
||||
|
||||
@ -281,8 +281,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
|
||||
for either class should be equal unless the custom delegate needs to use
|
||||
the style for drawing.
|
||||
|
||||
\sa {Delegate Classes}, QStyledItemDelegate, QAbstractItemDelegate,
|
||||
{Spin Box Delegate Example}
|
||||
\sa {Delegate Classes}, QStyledItemDelegate, QAbstractItemDelegate
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -204,8 +204,7 @@ public:
|
||||
documentation for details.
|
||||
|
||||
\sa {Delegate Classes}, QItemDelegate, QAbstractItemDelegate, QStyle,
|
||||
{Spin Box Delegate Example}, {Star Delegate Example}, {Color
|
||||
Editor Factory Example}
|
||||
{Star Delegate Example}, {Color Editor Factory Example}
|
||||
*/
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user