PDA

View Full Version : Max height of a font and QHeaderView::resizeMode



tuli
28th February 2019, 00:02
Hey,

I have a QTableWidget, whose row-height I prefer to be as compact as possible without compromising the readability of the text-cell-content.
To achieve this I call


table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents );

Works perfect, but turns out to be very slow with larger models, to the point where I am looking at a blacked out window for seconds.
That makes sense, bc it has to look at fonts and styles etc and determine the height of many rows.


I have looked through the code and found the "setResizeContentsPrecision" method, however, even with very low values it isnt much of an improvement.

I *could* just do setSectionResizeMode(QHeaderView::Fixed) and then hardcode my preferred height.
But that would probably destroy UX across platforms, because this is really style and font dependent.



So the quest is to find a good, compact height. If I do setSectionResizeMode(QHeaderView::Fixed) and specify a height manually:


1. leaving the default the row-height is absurdly large, leaving tons of empty space.
2. if I use QFontMetric(font).lineheight() or QFontMetric(font).lineSpacing() then the height is too compact - it cuts off the lower pixels of a "p" or "q" or "g", for example. That makes the contents hard to read.
3. setDefaultSectionSize(QFontMetrics(table->font()).boundingRect("WIqgppÄ").height()); has the same problem - see this image for how it cuts off the last pixel(s) from "g":

https://i.imgur.com/KMpLZWV.png

i am on Qt 5.12 and Ubuntu18.04, but it's a cross platform app.

Sorry if this question isnt specific enough...

d_stranz
28th February 2019, 01:11
Works perfect, but turns out to be very slow with larger models, to the point where I am looking at a blacked out window for seconds.
That makes sense, bc it has to look at fonts and styles etc and determine the height of many rows.

I thought that QTableView only did calculations for what was actually displayed on screen, not the entire model. I could be wrong about this, or maybe QTableWidget behaves differently since it wraps its own model.

It may not be feasible for you, but maybe you could try using your own model and QTableView instead. For the model, you would need to implement Qt::SizeHintRole in the QAbstractItemModel::data() method to return the appropriate QSize for the row. You would also have the advantage that you could precompute the size and store the values in your model, and only update them when font or style changes.

tuli
28th February 2019, 01:27
As per the documentation I should be able to force it to only use the displayed rows by calling setResizeContentsPrecision(0), but that doesnt take the pressure off things... I will look into how much it actually accesses.

And I was sloppy in my previous post: I am not using a QTableWidget but indeed a QTableView with my own model.


For the model, you would need to implement Qt::SizeHintRole

I think it should be possible to find a constant one-fits-all value of line-height here. I dont mind wasting a few pixels here and there, but the default height is like 2x of a reasonable size.
For example, in practice and on my system this does nicely:



table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setDefaultSectionSize(QFontMetrics(table->font()).lineSpacing() + 4);


The +4 basically ensure there's enough space so the last pixels dont get cut off. But it bothers me a bit to hardcode such arbitrary values, when the final result depends on Fonts and Styles.