Trigger recompute of QListView item display
-
wrote on 25 Nov 2021, 02:46 last edited by
I've got a
QListView
that shows my items in two different modes, expanded and condensed. That's implemented using a delegate that overridespaint()
andsizeHint()
.paint()
loads my model data into a custom widget and renders it into the painter, andsizeHint()
returns that widget'ssizeHint()
. This works great for each individual mode, but when I cycle between them, the items that are currently onscreen are not updated to the new display, and the height of the rows stays at the height of the Expanded view's size hint (92px), even when sizeHint() starts returning the compact view's height(38px). What step am I missing to trigger the redraw of the current window contents, and to get the view to update to use the new sizeHint() for its row height calculation? -
You can try to emit a dataChanged() signal with the SizeHint role.
-
wrote on 25 Nov 2021, 06:23 last edited by
Good thought, thanks. Closer now, but still not quite there. The widgets all update when I mouse over the view now (but not before that), but their height stays the same as it was. For the record, here's what my (still not working) update function is doing right now:
self.ui.listPackages.updateGeometries() self.item_model.layoutChanged.emit() startIndex = self.item_model.index(0,0) endIndex = self.item_model.index(self.item_model.rowCount()-1,0) self.item_model.dataChanged.emit(startIndex, endIndex, Qt.SizeHintRole) for i in range(0,self.item_model.rowCount()): index = self.item_model.index(row,0) self.item_delegate.sizeHintChanged.emit(index)
I'm basically just throwing everything I can think of at it now, obviously once I find the real solution most of this will go away.
-
Not a python expert but dataChanged() needs a list/vector for the roles. If it would be c++ I would have called for a minimal example so I can check it out (there is a similar question around: https://forum.qt.io/topic/132284/ ).
What exact Qt version do you use? -
Not a python expert but dataChanged() needs a list/vector for the roles. If it would be c++ I would have called for a minimal example so I can check it out (there is a similar question around: https://forum.qt.io/topic/132284/ ).
What exact Qt version do you use?wrote on 25 Nov 2021, 08:10 last edited by@Christian-Ehrlicher said in Trigger recompute of QListView item display:
Not a python expert but dataChanged() needs a list/vector for the roles.
If it makes any difference @Chris-Hennes should try
self.item_model.dataChanged.emit(startIndex, endIndex, [Qt.SizeHintRole])
-
wrote on 25 Nov 2021, 16:27 last edited by
I tried with the role set to various things (as a list), but my basic impression is that nothing in Qt internally uses the role argument to
dataChanged()
, and it didn't have any effect here. I can create a short C++ example after the holiday here, if no other solution arises. I'm doing this development on 5.15, but any chosen solution has to work on 5.12 as well. -
Is it the same problem (in python) like here https://forum.qt.io/topic/132284/ ?
-
wrote on 25 Nov 2021, 18:57 last edited by
It's not the same problem, though it's possible they have related solutions: my rows aren't editable, so I don't create an editor widget at all, this is the main display that's not working quite right. I suspect in my case it's two independent problems. The first is that I need to trigger the
QListView
to redraw itself (which should trigger thepaint()
function in my delegate for the on-screen rows), and the second is that I need theQListView
to actually use thesizeHint()
that it's getting from that delegate. -
wrote on 26 Nov 2021, 02:10 last edited by
OK, the answer turns out to be that I had an error elsewhere in my code that was masking the real problem. To get the update done all I actually need is
self.item_model.layoutChanged.emit()
Thanks again for the assistance.
1/9