QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?
-
wrote on 31 Mar 2022, 11:32 last edited by
I am implementing a simple JSON viewer with a tree view and model which is based largely on the "Simple tree model" Qt example code (located at
<QT_DIR>/Src/qtbase/examples/widgets/itemviews/simpletreemodel
).In the
data()
function for the model, if I merely return the data in the 2nd column(index.column() == 1)
, it is displayed correctly except when the QVariant has type == QVariant::Bool. If the item evaluates totrue
, then the tree view automatically displays the text "true" in the value column; however, if it evaluates tofalse
, it stays empty and does not display the string "false".Even if I set up the data() function as follows, the behavior is the same (
AJTI
is a typedef forAbstractJsonTreeItem
which is the base class for my JSON items of different types):QVariant JsonTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); QVariant retval; int column = index.column(); AJTI *pItem = static_cast<AJTI*>(index.internalPointer()); switch(role) { case Qt::DisplayRole: retval = pItem->data(column); if (column == 1) { if ((retval.type() == QVariant::String) && retval.toString().isEmpty()) { retval = "---"; } else if (retval.type() == QVariant::Bool) { retval = retval.toBool() ? "true" : "false"; } } break; case RawDataRole: retval = pItem->data(column); break; default: break; } return retval; }
In the debugger, I can single-step into the data() function, and for the single element which is false in the JSON object, it sets the value to the string "false" as well as to "true" for other elements which are set to true. Also, the variant type changes from "QVariant(bool)" to "QVariant(string)". But in the QTreeView, the column is still empty when it should display "false"!
Is this a known bug?
-
I am implementing a simple JSON viewer with a tree view and model which is based largely on the "Simple tree model" Qt example code (located at
<QT_DIR>/Src/qtbase/examples/widgets/itemviews/simpletreemodel
).In the
data()
function for the model, if I merely return the data in the 2nd column(index.column() == 1)
, it is displayed correctly except when the QVariant has type == QVariant::Bool. If the item evaluates totrue
, then the tree view automatically displays the text "true" in the value column; however, if it evaluates tofalse
, it stays empty and does not display the string "false".Even if I set up the data() function as follows, the behavior is the same (
AJTI
is a typedef forAbstractJsonTreeItem
which is the base class for my JSON items of different types):QVariant JsonTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); QVariant retval; int column = index.column(); AJTI *pItem = static_cast<AJTI*>(index.internalPointer()); switch(role) { case Qt::DisplayRole: retval = pItem->data(column); if (column == 1) { if ((retval.type() == QVariant::String) && retval.toString().isEmpty()) { retval = "---"; } else if (retval.type() == QVariant::Bool) { retval = retval.toBool() ? "true" : "false"; } } break; case RawDataRole: retval = pItem->data(column); break; default: break; } return retval; }
In the debugger, I can single-step into the data() function, and for the single element which is false in the JSON object, it sets the value to the string "false" as well as to "true" for other elements which are set to true. Also, the variant type changes from "QVariant(bool)" to "QVariant(string)". But in the QTreeView, the column is still empty when it should display "false"!
Is this a known bug?
@Robert-Hairgrove said in QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?:
Even if I set up the data() function as follows, the behavior is the same
This can't be correct - check with your debugger if you really get there - if you return a string then this string will be displayed.
-
@Robert-Hairgrove said in QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?:
Even if I set up the data() function as follows, the behavior is the same
This can't be correct - check with your debugger if you really get there - if you return a string then this string will be displayed.
wrote on 31 Mar 2022, 11:43 last edited by@Christian-Ehrlicher I forgot to mention that I am using Qt version 5.12.9 on Linux Ubuntu (18.04).
In my last paragraph which comes after the code snippet, which you may have missed, I did mention the debugger.
-
Again - if you return a string with the word 'true' or 'false' then this is displayed. When you don't see something in your cell then this code was not called. Simply return 'TRUE' to see if you see it upper-cased in your cell.
-
Again - if you return a string with the word 'true' or 'false' then this is displayed. When you don't see something in your cell then this code was not called. Simply return 'TRUE' to see if you see it upper-cased in your cell.
wrote on 31 Mar 2022, 12:13 last edited by@Christian-Ehrlicher Here is my sample JSON file (from my Skype configuration):
{"app.registerProtocols":true,"app.checkNonAdmin":true,"main-window.zoom-level":0,"main-window.isMaximised":true,"main-window.position":{"x":77,"y":35,"width":1853,"height":1025},"app.shouldSendOptionalTelemetry":true,"app.autoStartEnabled":false}
And here is the output ... I changed the code to show "wahr" or "falsch" instead of "true" or "false" (note that the first element shows only the key):

-
@Robert-Hairgrove said in QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?:
retval.type()
Then this type os not QVariant::Bool but something different.
-
wrote on 31 Mar 2022, 12:41 last edited by
In the meantime, I found that it is whatever is in the first row that is hidden. If I rename the key to something starting with a text other than "app", such as "bapp", the underlying QJsonDocument keeps its members sorted by key, and the expected text is shown properly.
It must be something else in my own code, but I will have to investigate further.
-
In the meantime, I found that it is whatever is in the first row that is hidden. If I rename the key to something starting with a text other than "app", such as "bapp", the underlying QJsonDocument keeps its members sorted by key, and the expected text is shown properly.
It must be something else in my own code, but I will have to investigate further.
wrote on 31 Mar 2022, 12:44 last edited by@Robert-Hairgrove said in QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?:
the underlying QJsonDocument keeps its members sorted by key
We had a discussion about this recently, and in the past. You should not rely on the ordering of JSON members, alphabetically or anything else, as they are "unordered". If your code relies on an ordering it is susceptible of going wrong, now or in the future.
-
@Robert-Hairgrove said in QTreeView showing "true" for Boolean items which evaluate to true, but empty if false?:
the underlying QJsonDocument keeps its members sorted by key
We had a discussion about this recently, and in the past. You should not rely on the ordering of JSON members, alphabetically or anything else, as they are "unordered". If your code relies on an ordering it is susceptible of going wrong, now or in the future.
wrote on 31 Mar 2022, 13:17 last edited by@JonB Got it. I only renamed one of the keys so that it wouldn't be the first row, and this illustrates that the problem lies somewhere else. I never rely on the ordering of elements.
-
@JonB Got it. I only renamed one of the keys so that it wouldn't be the first row, and this illustrates that the problem lies somewhere else. I never rely on the ordering of elements.
wrote on 31 Mar 2022, 13:29 last edited by@Robert-Hairgrove
It seems the current implementation of Qt'sQJsonDocument
outputs object keys in alphabetical order when serializing (because it probably stores them in a map whose keys are ordered alphabetically). But that isn't documented/guaranteed/to be relied upon. (Indeed, in the recent other thread that OP was complaining about this and saying they wished it instead remembered/output in insertion order instead!) AndQJsonDocument
should certainly be happy to deserialize an object whose keys have been saved in any order.Certainly if you might accept a JSON file from another source, or if say a user edited/produced the JSON file, you cannot be sure what order the members might be in.
The fact that something went wrong when an object member was renamed seems to indicate there is some reliance on ordering somewhere in your code.
-
wrote on 31 Mar 2022, 13:56 last edited by
Problem is solved ... it was a stupid error on my part!
In a first attempt, I had set the first column to span both rows. After i changed the tree implementation, which should show both columns in every row, I forgot to take it out. :(
1/11