QTreeView doesn't show any content
I'm currently experiencing an issue with a
QTreeViewand a custom subclass of
QAbstractItemModel: The model is working well and returns the data it's supposed to return (I confirmed that with
qDebug()everywhere) but the
QTreeViewnever shows any data. I experienced that issues multiple times in the past when I first started to work with Qt models and that was always due to missing calls to
endInsertRows()in my model subclass but that's not the problem here.
I also tried using other views such as
QListView. It's always the same: The model appears to operate properly internally but the view doesn't show any content. Interesting is the fact that when I move the mouse cursor inside the view I see that the
data()method gets triggered all the time and according to the
qDebug()it also returns the correct data (a valid non-empty
I'd appreciate any help on this. Here are my sources:
- Qt 5.8.0 on Windows 10 using MinGW 5.3.0 32-bit
FindWidget::resultReady()method contains a
qDebug()on the model's
rowCount()which returns the expected non-zero value equal to the number of results that have been added to the model.
I just skimmed through the code, but at a first glance there are at least couple of bugs there:
reintrpret_castusage is completely wrong. That's definitely not what you meant.
reinterpret_castis a "Stay away compiler, I totally know what I'm doing" cast i.e. it will always succeed no matter if the types are related in any way or not. Needless to say you are often casting things assuming you'll get null if the thing is not the thing, but what you actually get is a garbage pointer.
- You are not checking the
ResultsModel::datawhich means you return a string for everything, including things like background color, font or size hint. You should only return that string if
role == Qt::DisplayRole.
- Your implementation of
rowCountcreates a tree of infinite depth because you're only checking for the top level and returning the number of files. For the second level you return the number of lines. For the third level you return the number of lines of something... and so on.
- In the implementation of
ResultsModel::addResultyou should call
createIndex. The only methods using
createIndex()directly should probably be
I hadn't time to go through the
parent()in detail, but by the sole amount of for loops for a simple two-level tree I'm betting there's something wrong there too. Keep in mind that
parent()are the most often called methods. It can easily go into hundreds at a time in a medium size data set. They should be as simple as possible and I have yet to see a case where a loop over everything would be needed.
Hello Chris, glad to see that you're still around! :)
- I agree with you that the use of
reinterpret_castis not proper here. This was meant to be just a very quick proof-of-concept implementation of a file search tool. I always find it somewhat inconvenient to pass pointers via
QVariantso being a bit in a hurry I decided to go the good old "I know what I'm doing" way.
QTreeViewis showing the expected data now that I added a check for
role != Qt::DisplayRolein my
data()method. I'm not sue how I could miss that. After all, it's not the first time I'm dealing with that. Probably one shouldn't do just quick proof-of-concept implementations of models :p
- Regarding the
rowCount()implementation: In my opinion this is correct. After all, this model only supports two levels of depth. It's just a list of files that contain multiple sub-results in form of line numbers. Or am I missing something? This is the first time I'm implementing a somewhat "make shift" model. I regret it already.
- Good catch on the
addResult(). I missed that one!
Thank you a lot for your help. Much appreciated!
- I agree with you that the use of
Err... I just realize what you actually were referring to regarding the issue with
reinterpret_cast.... Thanks Chris, much appreciated, as always! :)
After all, this model only supports two levels of depth.
Well yeah, you and I know that. But how is the tree view suppose to know that? It's not like it understands your intent ;)
The view discovers the amount of levels by calling
rowCount()until it returns 0, and you never do that (if there are any lines added) so it will let you expand and expand until it probably crashes at some point if you stumble upon an out of range index.
Chris, thank you a lot for your time to look into this. I appreciate it a lot.
I'll rewrite this properly. There's no point in going quick proof-of-concept on something like this.