Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquicktableviewdelegate.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7
8#include <QtQuickTemplates2/private/qquickitemdelegate_p_p.h>
9#include <QtQuick/private/qquicktaphandler_p.h>
10#include <QtQuick/private/qquicktableview_p.h>
11
12#include <QtCore/qpointer.h>
13
15
16/*!
17 \qmltype TableViewDelegate
18 \inherits ItemDelegate
19 \inqmlmodule QtQuick.Controls
20 \since 6.9
21 \ingroup qtquickcontrols-delegates
22 \brief A delegate that can be assigned to a TableView.
23
24 \image qtquickcontrols-tableviewdelegate.png
25 {Table view displaying addresses using a table view delegate}
26
27 A TableViewDelegate is a delegate that can be assigned to the
28 \l {TableView::delegate} {delegate property} of a \l TableView.
29 It renders each cell of the table in the view using the application style.
30
31 \code
32 TableView {
33 anchors.fill: parent
34 delegate: TableViewDelegate {}
35 // model: yourModel
36 }
37 \endcode
38
39 TableViewDelegate inherits \l ItemDelegate, which means that it's composed of
40 two items: a \l[QML]{Control::}{background} and a \l [QML]{Control::}{contentItem}.
41
42 The position of the contentItem is controlled with \l [QML]{Control::}{padding}.
43
44 \section2 Interacting with pointers
45 TableViewDelegate inherits \l ItemDelegate. This means that it will emit signals such as
46 \l {AbstractButton::clicked()}{clicked} when the user clicks on the delegate.
47 You can connect to this signal to implement application-specific functionality.
48
49 However, the ItemDelegate API does not give you information about the position of the
50 click, or which modifiers are being held. If this is needed, a better approach would
51 be to use pointer handlers, for example:
52
53 \code
54 TableView {
55 id: tableView
56 delegate: TableViewDelegate {
57 TapHandler {
58 acceptedButtons: Qt.RightButton
59 onTapped: someContextMenu.open()
60 }
61
62 TapHandler {
63 acceptedModifiers: Qt.ControlModifier
64 onTapped: tableView.doSomethingToCell(row, column)
65 }
66 }
67 }
68 \endcode
69
70 \note If you want to disable the default behavior that occurs when the
71 user clicks on the delegate (like changing the current index), you can set
72 \l {TableView::pointerNavigationEnabled}{pointerNavigationEnabled} to \c false.
73
74 \section2 Editing cells in the table
75 TableViewDelegate has a default \l {TableView::editDelegate}{edit delegate} assigned.
76 If \l TableView has \l {TableView::editTriggers}{edit triggers} set, and
77 the \l {TableView::model}{model} has support for \l {Editing cells} {editing model items},
78 then the user can activate any of the edit triggers to edit the text of
79 the \l {TableViewDelegate::current}{current} table cell.
80
81 The default edit delegate will use the \c {Qt.EditRole} to read and write data to the
82 \l {TableView::model}{model}. If you need to use another role, or otherwise have needs
83 outside what the default edit delegate offers, you can always assign your own delegate
84 to \l {TableView::editDelegate}{TableView.editDelegate}.
85
86 \sa {Customizing TableViewDelegate}, {TableView}
87*/
88
89/*!
90 \qmlproperty TableView QtQuick.Controls::TableViewDelegate::tableView
91
92 This property points to the \l TableView that contains the delegate item.
93*/
94
95/*!
96 \qmlproperty bool QtQuick.Controls::TableViewDelegate::current
97
98 This property holds whether or not the delegate represents the
99 \l {QItemSelectionModel::currentIndex()}{current index}
100 in the \l {TableView::selectionModel}{selection model}.
101*/
102
103/*!
104 \qmlproperty bool QtQuick.Controls::TableViewDelegate::selected
105
106 This property holds whether or not the delegate represents a
107 \l {QItemSelectionModel::selection()}{selected index}
108 in the \l {TableView::selectionModel}{selection model}.
109*/
110
111/*!
112 \qmlproperty bool QtQuick.Controls::TableViewDelegate::editing
113
114 This property holds whether or not the delegate is being \l {Editing cells}{edited}.
115*/
116
117using namespace Qt::Literals::StringLiterals;
118
119QQuickTableViewDelegate::QQuickTableViewDelegate(QQuickItem *parent)
120 : QQuickItemDelegate(*(new QQuickTableViewDelegatePrivate), parent)
121{
122 Q_D(QQuickTableViewDelegate);
123
124 auto tapHandler = new QQuickTapHandler(this);
125 tapHandler->setAcceptedModifiers(Qt::NoModifier);
126
127 // Since we override mousePressEvent to avoid QQuickAbstractButton from blocking
128 // pointer handlers, we inform the button about its pressed state from the tap
129 // handler instead. This will ensure that we emit button signals like
130 // pressed, clicked, and doubleClicked.
131 connect(tapHandler, &QQuickTapHandler::pressedChanged, this, [this, d, tapHandler] {
132 auto view = tableView();
133 if (!view || !view->pointerNavigationEnabled())
134 return;
135
136 const QQuickHandlerPoint p = tapHandler->point();
137 if (tapHandler->isPressed())
138 d->handlePress(p.position(), 0);
139 else if (tapHandler->tapCount() > 0)
140 d->handleRelease(p.position(), 0);
141 else
142 d->handleUngrab();
143
144 if (tapHandler->tapCount() > 1 && !tapHandler->isPressed())
145 emit doubleClicked();
146 }, Qt::DirectConnection);
147}
148
149QQuickTableViewDelegate::QQuickTableViewDelegate(QQuickTableViewDelegatePrivate &dd, QQuickItem *parent)
150 : QQuickItemDelegate(dd, parent)
151{
152}
153
154void QQuickTableViewDelegate::mousePressEvent(QMouseEvent *event)
155{
156 Q_D(QQuickTableViewDelegate);
157
158 const auto view = d->m_tableView;
159 if (view && view->pointerNavigationEnabled()) {
160 // Ignore mouse events so that we don't block our own pointer handlers, or
161 // pointer handlers in e.g TreeView, TableView, or SelectionRectangle. Instead
162 // we call out to the needed mouse handling functions in QQuickAbstractButton directly
163 // from our pointer handlers, to ensure that we continue to work as a button.
164 event->ignore();
165 return;
166 }
167
168 QQuickItemDelegate::mousePressEvent(event);
169}
170
171QPalette QQuickTableViewDelegatePrivate::defaultPalette() const
172{
173 return QQuickTheme::palette(QQuickTheme::ItemView);
174}
175
176QFont QQuickTableViewDelegate::defaultFont() const
177{
178 return QQuickTheme::font(QQuickTheme::ItemView);
179}
180
181bool QQuickTableViewDelegate::current() const
182{
183 return d_func()->current;
184}
185
186void QQuickTableViewDelegate::setCurrent(bool current)
187{
188 Q_D(QQuickTableViewDelegate);
189 if (d->current == current)
190 return;
191
192 d->current = current;
193 emit currentChanged();
194}
195
196bool QQuickTableViewDelegate::selected() const
197{
198 return d_func()->selected;
199}
200
201void QQuickTableViewDelegate::setSelected(bool selected)
202{
203 Q_D(QQuickTableViewDelegate);
204 if (d->selected == selected)
205 return;
206
207 d->selected = selected;
208 emit selectedChanged();
209}
210
211bool QQuickTableViewDelegate::editing() const
212{
213 return d_func()->editing;
214}
215
216void QQuickTableViewDelegate::setEditing(bool editing)
217{
218 Q_D(QQuickTableViewDelegate);
219 if (d->editing == editing)
220 return;
221
222 d->editing = editing;
223 emit editingChanged();
224}
225
226QQuickTableView *QQuickTableViewDelegate::tableView() const
227{
228 return d_func()->m_tableView;
229}
230
231void QQuickTableViewDelegate::setTableView(QQuickTableView *tableView)
232{
233 Q_D(QQuickTableViewDelegate);
234 if (d->m_tableView == tableView)
235 return;
236
237 d->m_tableView = tableView;
238 emit tableViewChanged();
239}
240
241QT_END_NAMESPACE
242
243#include "moc_qquicktableviewdelegate_p.cpp"
Combined button and popup list for selecting options.