Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstyleditemdelegate.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
5
7#include <qapplication.h>
8#include <qbrush.h>
9#if QT_CONFIG(lineedit)
10#include <qlineedit.h>
11#endif
12#if QT_CONFIG(textedit)
13#include <qtextedit.h>
14#include <qplaintextedit.h>
15#endif
16#include <qpainter.h>
17#include <qpalette.h>
18#include <qpoint.h>
19#include <qrect.h>
20#include <qsize.h>
21#include <qstyle.h>
22#include <qdatetime.h>
23#include <qstyleoption.h>
24#include <qevent.h>
25#include <qpixmap.h>
26#include <qbitmap.h>
27#include <qpixmapcache.h>
28#include <qitemeditorfactory.h>
29#include <private/qitemeditorfactory_p.h>
30#include <qmetaobject.h>
31#include <qtextlayout.h>
32#include <private/qabstractitemdelegate_p.h>
33#include <private/qabstractitemmodel_p.h>
34#include <private/qtextengine_p.h>
35#include <private/qlayoutengine_p.h>
36#include <qdebug.h>
37#include <qlocale.h>
38#if QT_CONFIG(tableview)
39#include <qtableview.h>
40#endif
41
42#include <array>
43#include <limits.h>
44
46
48{
49 Q_DECLARE_PUBLIC(QStyledItemDelegate)
50
51public:
53
54 static const QWidget *widget(const QStyleOptionViewItem &option)
55 {
56 return option.widget;
57 }
58
60 {
62 }
63
65
66 mutable std::array<QModelRoleData, 7> modelRoleData = {
74 };
75};
76
217{
218}
219
224{
225}
226
241{
242 return d_func()->textForRole(Qt::DisplayRole, value, locale);
243}
244
253 const QModelIndex &index) const
254{
255 option->index = index;
256
257 Q_D(const QStyledItemDelegate);
258 QModelRoleDataSpan modelRoleDataSpan = d->modelRoleData;
259 index.multiData(modelRoleDataSpan);
260
261 const QVariant *value;
262 value = modelRoleDataSpan.dataForRole(Qt::FontRole);
263 if (value->isValid() && !value->isNull()) {
264 option->font = qvariant_cast<QFont>(*value).resolve(option->font);
265 option->fontMetrics = QFontMetrics(option->font);
266 }
267
268 value = modelRoleDataSpan.dataForRole(Qt::TextAlignmentRole);
269 if (value->isValid() && !value->isNull())
270 option->displayAlignment = QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(*value);
271
272 value = modelRoleDataSpan.dataForRole(Qt::ForegroundRole);
273 if (value->canConvert<QBrush>())
274 option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(*value));
275
276 value = modelRoleDataSpan.dataForRole(Qt::CheckStateRole);
277 if (value->isValid() && !value->isNull()) {
278 option->features |= QStyleOptionViewItem::HasCheckIndicator;
279 option->checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(*value);
280 }
281
282 value = modelRoleDataSpan.dataForRole(Qt::DecorationRole);
283 if (value->isValid() && !value->isNull()) {
284 option->features |= QStyleOptionViewItem::HasDecoration;
285 switch (value->userType()) {
286 case QMetaType::QIcon: {
287 option->icon = qvariant_cast<QIcon>(*value);
288 if (option->icon.isNull()) {
289 option->features &= ~QStyleOptionViewItem::HasDecoration;
290 break;
291 }
293 if (!(option->state & QStyle::State_Enabled))
295 else if (option->state & QStyle::State_Selected)
297 else
300 QSize actualSize = option->icon.actualSize(option->decorationSize, mode, state);
301 // For highdpi icons actualSize might be larger than decorationSize, which we don't want. Clamp it to decorationSize.
302 option->decorationSize = QSize(qMin(option->decorationSize.width(), actualSize.width()),
303 qMin(option->decorationSize.height(), actualSize.height()));
304 break;
305 }
306 case QMetaType::QColor: {
307 QPixmap pixmap(option->decorationSize);
308 pixmap.fill(qvariant_cast<QColor>(*value));
309 option->icon = QIcon(pixmap);
310 break;
311 }
312 case QMetaType::QImage: {
313 QImage image = qvariant_cast<QImage>(*value);
315 option->decorationSize = image.deviceIndependentSize().toSize();
316 break;
317 }
318 case QMetaType::QPixmap: {
319 QPixmap pixmap = qvariant_cast<QPixmap>(*value);
320 option->icon = QIcon(pixmap);
321 option->decorationSize = pixmap.deviceIndependentSize().toSize();
322 break;
323 }
324 default:
325 break;
326 }
327 }
328
329 value = modelRoleDataSpan.dataForRole(Qt::DisplayRole);
330 if (value->isValid() && !value->isNull()) {
331 option->features |= QStyleOptionViewItem::HasDisplay;
332 option->text = displayText(*value, option->locale);
333 }
334
335 value = modelRoleDataSpan.dataForRole(Qt::BackgroundRole);
336 option->backgroundBrush = qvariant_cast<QBrush>(*value);
337
338 // disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
339 option->styleObject = nullptr;
340}
341
365 const QStyleOptionViewItem &option, const QModelIndex &index) const
366{
367 Q_ASSERT(index.isValid());
368
369 QStyleOptionViewItem opt = option;
371
373 QStyle *style = widget ? widget->style() : QApplication::style();
375}
376
387QSize QStyledItemDelegate::sizeHint(const QStyleOptionViewItem &option,
388 const QModelIndex &index) const
389{
391 if (value.isValid())
392 return qvariant_cast<QSize>(value);
393
394 QStyleOptionViewItem opt = option;
397 QStyle *style = widget ? widget->style() : QApplication::style();
399}
400
409 const QStyleOptionViewItem &option,
410 const QModelIndex &index) const
411{
413 Q_D(const QStyledItemDelegate);
414 if (!index.isValid())
415 return nullptr;
416 return d->editorFactory()->createEditor(index.data(Qt::EditRole).userType(), parent);
417}
418
429{
431 QByteArray n = editor->metaObject()->userProperty().name();
432
433 if (!n.isEmpty()) {
434 if (!v.isValid())
435 v = QVariant(editor->property(n).metaType());
436 editor->setProperty(n, v);
437 }
438}
439
452 const QModelIndex &index) const
453{
454 Q_D(const QStyledItemDelegate);
456 Q_ASSERT(editor);
457 QByteArray n = editor->metaObject()->userProperty().name();
458 if (n.isEmpty())
459 n = d->editorFactory()->valuePropertyName(
461 if (!n.isEmpty())
462 model->setData(index, editor->property(n), Qt::EditRole);
463}
464
470 const QStyleOptionViewItem &option,
471 const QModelIndex &index) const
472{
473 if (!editor)
474 return;
475 Q_ASSERT(index.isValid());
477
478 QStyleOptionViewItem opt = option;
480 // let the editor take up all available space
481 //if the editor is not a QLineEdit
482 //or it is in a QTableView
483#if QT_CONFIG(tableview) && QT_CONFIG(lineedit)
484 if (qobject_cast<QExpandingLineEdit*>(editor) && !qobject_cast<const QTableView*>(widget))
485 opt.showDecorationSelected = editor->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, editor);
486 else
487#endif
488 opt.showDecorationSelected = true;
489
490 QStyle *style = widget ? widget->style() : QApplication::style();
492 editor->setGeometry(geom);
493}
494
502{
503 Q_D(const QStyledItemDelegate);
504 return d->factory;
505}
506
515{
517 d->factory = factory;
518}
519
520
553{
555 return d->editorEventFilter(object, event);
556}
557
563 const QStyleOptionViewItem &option,
564 const QModelIndex &index)
565{
568
569 // make sure that the item is checkable
570 Qt::ItemFlags flags = model->flags(index);
572 || !(flags & Qt::ItemIsEnabled))
573 return false;
574
575 // make sure that we have a check state
577 if (!value.isValid())
578 return false;
579
581 QStyle *style = widget ? widget->style() : QApplication::style();
582
583 // make sure that we have the right event type
584 if ((event->type() == QEvent::MouseButtonRelease)
585 || (event->type() == QEvent::MouseButtonDblClick)
586 || (event->type() == QEvent::MouseButtonPress)) {
587 QStyleOptionViewItem viewOpt(option);
588 initStyleOption(&viewOpt, index);
590 QMouseEvent *me = static_cast<QMouseEvent*>(event);
591 if (me->button() != Qt::LeftButton || !checkRect.contains(me->position().toPoint()))
592 return false;
593
594 if ((event->type() == QEvent::MouseButtonPress)
595 || (event->type() == QEvent::MouseButtonDblClick))
596 return true;
597
598 } else if (event->type() == QEvent::KeyPress) {
599 if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
600 && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
601 return false;
602 } else {
603 return false;
604 }
605
606 Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
608 state = ((Qt::CheckState)((state + 1) % 3));
609 else
612}
613
615
616#include "moc_qstyleditemdelegate.cpp"
The QAbstractItemDelegate class is used to display and edit data items from a model.
virtual Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Sets the role data for the item at index to value.
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
static QStyle * style()
Returns the application's style object.
\inmodule QtGui
Definition qbrush.h:30
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qcoreevent.h:45
@ KeyPress
Definition qcoreevent.h:64
@ MouseButtonPress
Definition qcoreevent.h:60
@ MouseButtonDblClick
Definition qcoreevent.h:62
@ MouseButtonRelease
Definition qcoreevent.h:61
\reentrant \inmodule QtGui
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Disabled
Definition qicon.h:22
@ Selected
Definition qicon.h:22
@ Normal
Definition qicon.h:22
State
This enum describes the state for which a pixmap is intended to be used.
Definition qicon.h:23
@ Off
Definition qicon.h:23
@ On
Definition qicon.h:23
\inmodule QtGui
Definition qimage.h:37
The QItemEditorFactory class provides widgets for editing item data in views and delegates.
static const QItemEditorFactory * defaultFactory()
Returns the default item editor factory.
The QKeyEvent class describes a key event.
Definition qevent.h:423
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:433
\inmodule QtCore
constexpr QVariant * dataForRole(int role) const
Returns the data associated with the first QModelRoleData in the span that has its role equal to role...
\inmodule QtCore
\inmodule QtGui
Definition qevent.h:195
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition qpixmap.cpp:1445
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:394
\inmodule QtCore\reentrant
Definition qrect.h:30
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:851
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Definition qevent.h:118
Qt::MouseButton button() const
Returns the button that caused the event.
Definition qevent.h:115
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const override
Returns the value for the specified item and role.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ State_Open
Definition qstyle.h:85
@ State_Enabled
Definition qstyle.h:67
@ State_Selected
Definition qstyle.h:82
@ CT_ItemViewItem
Definition qstyle.h:567
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
@ SH_ItemView_ShowDecorationSelected
Definition qstyle.h:643
@ CE_ItemViewItem
Definition qstyle.h:230
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const =0
Returns the sub-area for the given element as described in the provided style option.
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const =0
Draws the given element with the provided painter with the style options specified by option.
@ SE_ItemViewItemCheckIndicator
Definition qstyle.h:275
@ SE_ItemViewItemText
Definition qstyle.h:305
static const QWidget * widget(const QStyleOptionViewItem &option)
std::array< QModelRoleData, 7 > modelRoleData
const QItemEditorFactory * editorFactory() const
The QStyledItemDelegate class provides display and editing facilities for data items from a model.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Sets the data to be displayed and edited by the editor from the data model item specified by the mode...
virtual QString displayText(const QVariant &value, const QLocale &locale) const
This function returns the string that the delegate will use to display the Qt::DisplayRole of the mod...
QStyledItemDelegate(QObject *parent=nullptr)
Constructs an item delegate with the given parent.
~QStyledItemDelegate()
Destroys the item delegate.
void setItemEditorFactory(QItemEditorFactory *factory)
Sets the editor factory to be used by the item delegate to be the factory specified.
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
\reimp
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Gets data from the editor widget and stores it in the specified model at the item index.
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
Initialize option with the values using the index index.
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Updates the editor for the item specified by index according to the style option given.
QItemEditorFactory * itemEditorFactory() const
Returns the editor factory used by the item delegate.
bool eventFilter(QObject *object, QEvent *event) override
Returns true if the given editor is a valid QWidget and the given event is handled; otherwise returns...
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Returns the widget used to edit the item specified by index for editing.
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
Returns the size needed by the delegate to display the item specified by index, taking into account t...
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Renders the delegate using the given painter and style option for the item specified by index.
\inmodule QtCore
Definition qvariant.h:64
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
int userType() const
Definition qvariant.h:336
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QStyle * style() const
Definition qwidget.cpp:2607
QOpenGLWidget * widget
[1]
QStyleOptionButton opt
else opt state
[0]
Combined button and popup list for selecting options.
CheckState
@ Unchecked
@ Checked
@ LeftButton
Definition qnamespace.h:57
@ FontRole
@ TextAlignmentRole
@ ForegroundRole
@ DecorationRole
@ BackgroundRole
@ EditRole
@ CheckStateRole
@ DisplayRole
@ SizeHintRole
@ Key_Select
@ Key_Space
Definition qnamespace.h:512
@ ItemIsUserTristate
@ ItemIsUserCheckable
@ ItemIsEnabled
Definition image.cpp:4
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLsizei const GLfloat * v
[13]
GLenum mode
GLuint64 key
GLuint index
[2]
GLbitfield flags
GLfloat n
struct _cl_event * event
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_UNUSED(x)
QSqlQueryModel * model
[16]
QObject::connect nullptr
QItemEditorFactory * factory
widget render & pixmap
QPainter painter(this)
[7]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent