QList/Table/TreeWidgetItem: Allow reseting values by passing the default value

The convenience functions setBackground(), setForeground() and
setSizeHint() a default constructed value as 'reset'. This means a
default constructed QBrush or QSize is returned in the data() function
which leads to an unexpected background or forground color or size hint.
Therefore check if the passed value is a default constructed value and
set an empty QVariant instead which.

[ChangeLog][QtWidgets][ItemViews] The convenience views
QList/Table/TreeWidgetItem now treat a default constructed QBrush or
QSize as an empty QVariant which allows to reset the values set to it's
default values.

Task-number: QTBUG-76423
Change-Id: I840570bbad3e5fd8c5b4b58903b4fd0066dbdeb7
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Christian Ehrlicher 2019-06-25 20:47:13 +02:00
parent 2c871dfd38
commit 96c27eb710
9 changed files with 80 additions and 16 deletions

View File

@ -987,8 +987,9 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
\fn void QListWidgetItem::setSizeHint(const QSize &size)
\since 4.1
Sets the size hint for the list item to be \a size. If no size hint is set,
the item delegate will compute the size hint based on the item data.
Sets the size hint for the list item to be \a size.
If no size hint is set or \a size is invalid, the item
delegate will compute the size hint based on the item data.
*/
/*!
@ -1119,6 +1120,8 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
\since 4.2
Sets the background brush of the list item to the given \a brush.
Setting a default-constructed brush will let the view use the
default color from the style.
\sa background(), setForeground()
*/
@ -1137,6 +1140,8 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
\since 4.2
Sets the foreground brush of the list item to the given \a brush.
Setting a default-constructed brush will let the view use the
default color from the style.
\sa foreground(), setBackground()
*/

View File

@ -127,7 +127,7 @@ public:
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
inline void setBackground(const QBrush &brush)
{ setData(Qt::BackgroundRole, brush); }
{ setData(Qt::BackgroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
#if QT_DEPRECATED_SINCE(5, 13)
QT_DEPRECATED_X ("Use QListWidgetItem::foreground() instead")
@ -141,7 +141,7 @@ public:
inline QBrush foreground() const
{ return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
inline void setForeground(const QBrush &brush)
{ setData(Qt::ForegroundRole, brush); }
{ setData(Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState() const
{ return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
@ -151,7 +151,7 @@ public:
inline QSize sizeHint() const
{ return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
inline void setSizeHint(const QSize &size)
{ setData(Qt::SizeHintRole, size); }
{ setData(Qt::SizeHintRole, size.isValid() ? QVariant(size) : QVariant()); }
virtual QVariant data(int role) const;
virtual void setData(int role, const QVariant &value);

View File

@ -1064,8 +1064,8 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange()
\since 4.1
Sets the size hint for the table item to be \a size.
If no size hint is set, the item delegate will compute the
size hint based on the item data.
If no size hint is set or \a size is invalid, the item
delegate will compute the size hint based on the item data.
*/
/*!
@ -1279,6 +1279,8 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
\since 4.2
Sets the item's background brush to the specified \a brush.
Setting a default-constructed brush will let the view use the
default color from the style.
\sa setForeground()
*/
@ -1313,6 +1315,8 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
\since 4.2
Sets the item's foreground brush to the specified \a brush.
Setting a default-constructed brush will let the view use the
default color from the style.
\sa setBackground()
*/

View File

@ -146,7 +146,7 @@ public:
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
inline void setBackground(const QBrush &brush)
{ setData(Qt::BackgroundRole, brush); }
{ setData(Qt::BackgroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
#if QT_DEPRECATED_SINCE(5, 13)
QT_DEPRECATED_X ("Use QTableWidgetItem::foreground() instead")
@ -160,7 +160,7 @@ public:
inline QBrush foreground() const
{ return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
inline void setForeground(const QBrush &brush)
{ setData(Qt::ForegroundRole, brush); }
{ setData(Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState() const
{ return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
@ -170,7 +170,7 @@ public:
inline QSize sizeHint() const
{ return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
inline void setSizeHint(const QSize &size)
{ setData(Qt::SizeHintRole, size); }
{ setData(Qt::SizeHintRole, size.isValid() ? QVariant(size) : QVariant()); }
virtual QVariant data(int role) const;
virtual void setData(int role, const QVariant &value);

View File

@ -1285,6 +1285,8 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const
Sets the background brush of the label in the given \a column to the
specified \a brush.
Setting a default-constructed brush will let the view use the
default color from the style.
\note If \l{Qt Style Sheets} are used on the same widget as setBackground(),
style sheets will take precedence if the settings conflict.
@ -1314,6 +1316,8 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const
Returns the brush used to render the foreground (e.g. text) of the
specified \a column.
Setting a default-constructed brush will let the view use the
default color from the style.
\sa background()
*/
@ -1357,8 +1361,8 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const
\since 4.1
Sets the size hint for the tree item in the given \a column to be \a size.
If no size hint is set, the item delegate will compute the size hint based
on the item data.
If no size hint is set or \a size is invalid, the item
delegate will compute the size hint based on the item data.
*/
/*!

View File

@ -146,7 +146,7 @@ public:
inline QBrush background(int column) const
{ return qvariant_cast<QBrush>(data(column, Qt::BackgroundRole)); }
inline void setBackground(int column, const QBrush &brush)
{ setData(column, Qt::BackgroundRole, brush); }
{ setData(column, Qt::BackgroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
#if QT_DEPRECATED_SINCE(5, 13)
QT_DEPRECATED_X ("Use QTreeWidgetItem::foreground() instead")
@ -160,7 +160,7 @@ public:
inline QBrush foreground(int column) const
{ return qvariant_cast<QBrush>(data(column, Qt::ForegroundRole)); }
inline void setForeground(int column, const QBrush &brush)
{ setData(column, Qt::ForegroundRole, brush); }
{ setData(column, Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState(int column) const
{ return static_cast<Qt::CheckState>(data(column, Qt::CheckStateRole).toInt()); }
@ -170,7 +170,7 @@ public:
inline QSize sizeHint(int column) const
{ return qvariant_cast<QSize>(data(column, Qt::SizeHintRole)); }
inline void setSizeHint(int column, const QSize &size)
{ setData(column, Qt::SizeHintRole, size); }
{ setData(column, Qt::SizeHintRole, size.isValid() ? QVariant(size) : QVariant()); }
virtual QVariant data(int column, int role) const;
virtual void setData(int column, int role, const QVariant &value);

View File

@ -1512,6 +1512,20 @@ void tst_QListWidget::itemData()
QCOMPARE(flags.count(), 6);
for (int i = 0; i < 4; ++i)
QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
item.setBackground(QBrush(Qt::red));
item.setForeground(QBrush(Qt::red));
item.setSizeHint(QSize(10, 10));
QCOMPARE(item.data(Qt::BackgroundRole), QVariant(QBrush(Qt::red)));
QCOMPARE(item.data(Qt::ForegroundRole), QVariant(QBrush(Qt::red)));
QCOMPARE(item.data(Qt::SizeHintRole), QVariant(QSize(10, 10)));
// an empty brush should result in a QVariant()
item.setBackground(QBrush());
item.setForeground(QBrush());
item.setSizeHint(QSize());
QCOMPARE(item.data(Qt::BackgroundRole), QVariant());
QCOMPARE(item.data(Qt::ForegroundRole), QVariant());
QCOMPARE(item.data(Qt::SizeHintRole), QVariant());
}
void tst_QListWidget::changeDataWithSorting()

View File

@ -1404,9 +1404,17 @@ void tst_QTableWidget::setItemData()
QCOMPARE(table.currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole, Qt::ToolTipRole}));
QCOMPARE(table.model()->data(idx, Qt::DisplayRole).toString(), QLatin1String("Display"));
QCOMPARE(table.model()->data(idx, Qt::EditRole).toString(), QLatin1String("Display"));
QCOMPARE(table.model()->data(idx, Qt::ToolTipRole).toString(), QLatin1String("ToolTip"));
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(idx, qvariant_cast<QModelIndex>(dataChangedSpy.takeFirst().at(0)));
QCOMPARE(idx, qvariant_cast<QModelIndex>(dataChangedSpy.first().at(0)));
QCOMPARE(idx, qvariant_cast<QModelIndex>(dataChangedSpy.first().at(1)));
const auto roles = qvariant_cast<QVector<int>>(dataChangedSpy.first().at(2));
QCOMPARE(roles.size(), 3);
QVERIFY(roles.contains(Qt::DisplayRole));
QVERIFY(roles.contains(Qt::EditRole));
QVERIFY(roles.contains(Qt::ToolTipRole));
dataChangedSpy.clear();
table.model()->setItemData(idx, data);
QCOMPARE(dataChangedSpy.count(), 0);
@ -1416,6 +1424,21 @@ void tst_QTableWidget::setItemData()
table.model()->setItemData(idx, data);
QCOMPARE(table.model()->data(idx, Qt::DisplayRole).toString(), QLatin1String("dizplaye"));
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(QVector<int>({Qt::DisplayRole, Qt::EditRole}), qvariant_cast<QVector<int>>(dataChangedSpy.first().at(2)));
item->setBackground(QBrush(Qt::red));
item->setForeground(QBrush(Qt::green));
item->setSizeHint(QSize(10, 10));
QCOMPARE(item->data(Qt::BackgroundRole), QVariant(QBrush(Qt::red)));
QCOMPARE(item->data(Qt::ForegroundRole), QVariant(QBrush(Qt::green)));
QCOMPARE(item->data(Qt::SizeHintRole), QVariant(QSize(10, 10)));
// an empty brush should result in a QVariant()
item->setBackground(QBrush());
item->setForeground(QBrush());
item->setSizeHint(QSize());
QCOMPARE(item->data(Qt::BackgroundRole), QVariant());
QCOMPARE(item->data(Qt::ForegroundRole), QVariant());
QCOMPARE(item->data(Qt::SizeHintRole), QVariant());
}
void tst_QTableWidget::cellWidget()

View File

@ -1994,6 +1994,20 @@ void tst_QTreeWidget::itemData()
QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
flags = widget.model()->itemData(widget.model()->index(0, 1));
QCOMPARE(flags.count(), 0);
item.setBackground(0, QBrush(Qt::red));
item.setForeground(0, QBrush(Qt::green));
item.setSizeHint(0, QSize(10, 10));
QCOMPARE(item.data(0, Qt::BackgroundRole), QVariant(QBrush(Qt::red)));
QCOMPARE(item.data(0, Qt::ForegroundRole), QVariant(QBrush(Qt::green)));
QCOMPARE(item.data(0, Qt::SizeHintRole), QVariant(QSize(10, 10)));
// an empty brush should result in a QVariant()
item.setBackground(0, QBrush());
item.setForeground(0, QBrush());
item.setSizeHint(0, QSize());
QCOMPARE(item.data(0, Qt::BackgroundRole), QVariant());
QCOMPARE(item.data(0, Qt::ForegroundRole), QVariant());
QCOMPARE(item.data(0, Qt::SizeHintRole), QVariant());
}
void tst_QTreeWidget::enableDisable()