[Interest] QVariant, enums and gcc (Qt 5.5 vs 5.6 vs 5.7)

Ch'Gans chgans at gna.org
Sat Nov 26 03:22:43 CET 2016


Hi there,

In a model/view class, i have a column which is Qt::ItemIsUserCheckable,
in my model's setData(), i do:
if (role == Qt::CheckStateRole && index.column() == VisibleColumn)
{
        Qt::CheckState state = value.value<Qt::CheckState>();
        item->visible = state == Qt::Checked;
        emit dataChanged(index, index);
        return true;
 }


This works well with Qt-5.7, Qt-5.6 (official binaries), but fails
with Qt-5.5 (official binaries) and Qt-5.6 (KUbuntu-16.10).

The reason is that when i click on the checkbox, QTableView call
setData() with an int-based QVariant (which contains the int value
corresponding to the Qt::CheckState enum member), and:
- In the former case, "value.value<Qt::CheckState>();" converts this
int to the correct Qt::CheckState enum
- In the later case, the int is always converted to "Qt::Unchecked"
(enum value = 0).

The difference of behaviour seems to be caused by the GCC version, not
by Qt version or official binaries vs linux distro.

If i add this debugging message:
qDebug() << value
                << value.value<int>()
                << Qt::CheckState(value.value<int>())
                << value.value<Qt::CheckState>();

Here is what i get:
- Qt-5.6, KUbunutu 16.10
QVariant(int, 0) 0 Qt::CheckState(Unchecked) Qt::CheckState(Unchecked)
QVariant(int, 2) 2 Qt::CheckState(Checked) Qt::CheckState(Unchecked)
- Qt 5.5, Offical binaries
QVariant(int, 0) 0 Qt::CheckState(Unchecked) Qt::CheckState(Unchecked)
QVariant(int, 2) 2 Qt::CheckState(Checked) Qt::CheckState(Unchecked)
- Qt-5.6, Offical binaries
QVariant(int, 0) 0 Qt::CheckState(Unchecked) Qt::CheckState(Unchecked)
QVariant(int, 2) 2 Qt::CheckState(Checked) Qt::CheckState(Checked)
- Qt-5.7, Offical binaries
QVariant(int, 0) 0 Qt::CheckState(Unchecked) Qt::CheckState(Unchecked)
QVariant(int, 2) 2 Qt::CheckState(Checked) Qt::CheckState(Checked)



The workaround for getting this working on all Qt version/compilers is
to convert the variant this way:
Qt::CheckState state = Qt::CheckState(value.value<int>());

I first wonder why does QTableView call setData with an int-based
QVariant for Qt::CheckStateRole while the documentation says that the
underlying data should be Qt::CheckState?

Why is QVariant behaviour changing depending on the compiler version?

Am i missing something or doing something wrong?

Chris



More information about the Interest mailing list