Solved QTreeView doesn't show any content
-
Hello folks,
I'm currently experiencing an issue with a
QTreeView
and a custom subclass ofQAbstractItemModel
: The model is working well and returns the data it's supposed to return (I confirmed that withqDebug()
everywhere) but theQTreeView
never 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 tobeginInsertRows()
andendInsertRows()
in my model subclass but that's not the problem here.I also tried using other views such as
QTableView
andQListView
. 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 thedata()
method gets triggered all the time and according to theqDebug()
it also returns the correct data (a valid non-emptyQVariant
object).I'd appreciate any help on this. Here are my sources:
Additional info:
- Qt 5.8.0 on Windows 10 using MinGW 5.3.0 32-bit
- The
FindWidget::resultReady()
method contains aqDebug()
on the model'srowCount()
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:
- The
reintrpret_cast
usage is completely wrong. That's definitely not what you meant.reinterpret_cast
is 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
role
parameter inResultsModel::data
which means you return a string for everything, including things like background color, font or size hint. You should only return that string ifrole == Qt::DisplayRole
. - Your implementation of
rowCount
creates 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::addResult
you should callindex
instead ofcreateIndex
. The only methods usingcreateIndex()
directly should probably beindex()
andparent()
.
I hadn't time to go through the
index()
andparent()
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 thatindex()
andparent()
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. - The
-
Hello Chris, glad to see that you're still around! :)
- I agree with you that the use of
reinterpret_cast
is 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 viaQVariant
so being a bit in a hurry I decided to go the good old "I know what I'm doing" way. - The
QTreeView
is showing the expected data now that I added a check forrole != Qt::DisplayRole
in mydata()
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
createIndex()
instead ofindex()
call inaddResult()
. 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 callingrowCount()
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.