Ah, thank you! No, I don't.
How is the delegate supposed to know about changed sizes when sizeHint() isn't even called though?
Where is it supposed to emit this signal?![]()
What I'd have to do after connecting the view's resize event to the delegate is basically to emit sizeHintChanged signals for the whole of my model. That just doesn't appear to be the "right" way to do it, does it?
After all, the cause for the update is completely "external", not something in the data itself (which is what I think that the delegate's sizeHintChanged signal is probably intended for).
Isn't there a way to just tell the view to recalculate its items' sizes? It works for 'growing' items already... Maybe I could try to simulate a model-reset with saving/restoring the view's selection-state if there isn't a "best practice way"? All of this seems to be rather hackish though. It thought there has to be a "clean" way to do it...
No, just for the visible items and only if their height changes. If an item already fits a single line, increasing the width of the item will not influence its height. Same goes the other way -- it seems logical to limit the maximum height of an item.
The cause for the update is the way you want each item displayed which is the responsibility of the delegate (or the view, depending how you look at it). If data was changing, you'd emit dataChanged().After all, the cause for the update is completely "external", not something in the data itself
Yes. Emit sizeHintChanged() from the delegate. Alternatively reimplement visualRect() in the view and force an update of the whole viewport.Isn't there a way to just tell the view to recalculate its items' sizes?
I'd have to keep track of all the items' heights in the delegate then...No, just for the visible items and only if their height changes.
I've found a simpler, but hackish solution:
http://doc.qt.io/qt-4.8/qlistview.html#spacing-prop
The event filter object that catches resize events for the view's viewport is connected to a slot that calls setSpacing(0) on the view.Setting this property when the view is visible will cause the items to be laid out again.
Now it 'works' ...
In the resize event you have access to both the old and the new size. Using those values it should be easy to decide whether the span changes or not.
Kind of not-so-very-performant solution.I've found a simpler, but hackish solution:
http://doc.qt.io/qt-4.8/qlistview.html#spacing-prop
You are right of course.
Since I need to display some richtext im my items, I'm now creating a QTextDocument on the stack for every sizeHint and paint of my delegate. That's really ugly.
How would I go about caching the visible items (rows)?
My solution would be to get a list from the view via indexAt and visualRect that is updated on every view-scrollbar-change. Than I could cache the data in the delegate and provide sizeHints and sizeHintChanged signals from there. Maybe with a hashtable row -> struct CacheData or something like that... Data for items that cease to be visible would be destroyed after some period.
Do you have any suggestions or comments?
Thank you for your help so far.
When using linear data in general QContignousCache is your friend. If you want a cache of QTextDocuments (or whatever else you need) for your items in the delegate, go ahead. I never tried this and I'm very interested about the resulting performance of such approach. It might not be a bad idea. When I was implementing a rich text delegate, I was reusing a single document for different items.
A single QTextDocument is probably not an option, since I suspect all the HTML /CSS parsing to be quite slow. I didn't measure anyhing yet, though. Still busy with other stuff. Richtext is not my friend. ^^
Have a happy new year![]()
Since I had the same problem (rows' heights) with a QTreeView now, I did some digging through Qt's source code.
Look what I've found:
That's all. See how the QModelIndex that is passed to sizeHintChanged is ignored? Any sizeHintChanged signal just triggers a relayout.Qt Code:
.../qtbase/src/widgets/itemviews$ grep -n sizeHintChanged * qabstractitemdelegate.cpp:163: \fn void QAbstractItemDelegate::sizeHintChanged(const QModelIndex &index) qabstractitemview.cpp:834: disconnect(d->itemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout())); qabstractitemview.cpp:843: connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);To copy to clipboard, switch view to plain text mode
Even more interesting is the doItemsLayout() slot. It is public and available in all of Qt's item view widgets, but it is not documented. That's exactly what I was looking for
Someone asked if he could rely on that on another forum a few years ago. So I'm going to repeat the question here.![]()
If it is undocumented and not a virtual method then you cannot expect the method to work in future Qt releases. Of course it is unlikely that it goes away until Qt 6.0.
Bookmarks