Solved QAbstractTableModel.data() called on full data, outside displayed ones
-
Please provide a minimal, compilable example so we can see what may go wrong.
-
Thanks @Christian-Ehrlicher , I was cleaning my code block by block to be able to show a lighter version here, and I started to be pretty sure the "problem" was comming from Qt as I had deleted almost every complicated thing from my code.
Then I found these lines :
self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table_view.horizontalHeader().setStretchLastSection(True)
They are the ones responsible, which acutally makes sense, Qt has to read all the data to find the max size of elements.
Results of my trials: number of full data access by state :
Open App / Show TableView for the 1st time / show-hide TableView again / Resize window H Resize2Contents : 1 2 1 Crazy V Resize2Contents : 0 3 1 Crazy H+V Resize2Contents : 2 4 2 Crazy H+V + HStretchLast : 2 6 2 Crazy HStretchLast only : 0 0 0 0
In the end this was totally unrelated to my model, *ResetModel, ... but to display options...
I hope this will save time to people in the future, who will think twice before using these functions that seem harmless !
-
A good example on why a simple reproducer is a good starting point.
See also QHeaderView::setResizeContentsPrecision - it may help you if you need to use this resize mode./edit: and please mark the topic as solved, thx.
-
@Christian-Ehrlicher Thanks again, exactly what I needed.
Still some strange behavior though :self.table_view.horizontalHeader().setResizeContentsPrecision(0) self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
Works fine if I force the view tab to be selected at startup. Else (maybe because it doesnt know how many rows will be displayed), it runs through the entire data.
On the other hand, the verticalHeader equivalent lines still process the whole data. Any idea why ?
For now I will set it to Fixed. -
'Special value 0 means that it will look at only the visible area.'
-
Someone should add a note to the documentation for those functions - its pathetically sparse and there should be ample warning.
-
Hi,
@Christian-Ehrlicher cited the content of the documentation of the function.
-
Pardon for posting in this old thread, but I found it during digging inside the same problem.
First, I thought that I found the solution here -setResizeContentsPrecision(0)
. But next, I tried to doself.view.verticalHeader().setResizeContentsPrecision(0) self.view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
and it fetches all rows... Should
setResizeContentsPrecision
work for vertical header also?
If not - is there any way to have rows of different height in QTableView without reading whole table data? -
@StarterKit said in QAbstractTableModel.data() called on full data, outside displayed ones:
If not - is there any way to have rows of different height in QTableView without reading whole table data?
No because then the size of the scrollbar can not be determined.
-
@Christian-Ehrlicher , yes, I see your point. But this is valid if we calculate scroll bar position based on row geometry. As alternative - we may calculate scroll bar size/position based on row count - it will give neglegible error for tables with tens of rows (and almost 0 error for large tables with hunderds -thousands rows...). I think it might be a useful feature of QTableVew/QHeaderView...
-
Feel free to provide a patch for it :)
-
@Christian-Ehrlicher said in QAbstractTableModel.data() called on full data, outside displayed ones:
Feel free to provide a patch for it :)
Ok, will read a bit about how to build Qt from source and make changes. Have never done it before.
-
@StarterKit Since you would like to create a patch (that's cool, thanks), don't try to build the whole of Qt since your patch is located in qtbase, you can just build that module and go hacking.
-
@SGaist thanks for the advice. I'll try to do it in spare time.
Right now I decided to play with
QTableView::setRowHeight()
. It appears to do the job quite well, but code structure looks ugly.
But looking how fast it does the job I really start thinking that it is a bug thatsetResizeContentsPrecision(0)
doesn't work for vertical header.I.e. as a first test I called
setRowHeight()
fromdata()
method of the model. This method is called many times for different roles and columns. And even in these non-optimal conditions it works well as it is called for visible rows only. And there are no problems with scrollbar at all - it works as it should. I assume withsetResizeContentsPrecision(0)
it may do the same or similar action but with only one call todata()
forSizeHintRole
.I reported QTBUG-100818 first of all for documentation, but mentioned there my doubts.