Update rect in delegate when changing content's size
-
In my own
QStyledItemDelegate
subclass, I change the visualized text:void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override { editor->setGeometry(option.rect); } void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); opt.text = opt.locale.toString(opt.locale.toFloat(opt.text), 'f', _decimals); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); }
basically, I format the floating-point number with the specified number of decimals.
It works, but I'm afraid theopt.rect
is not updated as well, since theQTableView
does not adjust the column with to the content when callingresizeColumnsToContents()
:both the columns have the above delegate.
I tried to add:opt.rect = opt.widget->rect();
at the end of the
paint()
function but nothing changed.
How should I handle the new size of the widget so theQTableView
can correctly adjust the columns? -
Hi,
Does your delegate return a suitable size hint ?
-
@SGaist said in Update rect in delegate when changing content's size:
Does your delegate return a suitable size hint ?
I asked him the same question 3 hours ago... https://stackoverflow.com/questions/79397528/how-to-update-geometry-of-item-delegate
-
@SGaist nope, I didn't understand its usage.
How to retrieve the correct size, then?I tried with:
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { return option.widget->sizeHint(); }
but now the column is too large:
-
Don't you think you should return something suitable to your requirements instead some default values?
-
@Christian-Ehrlicher I hope I'm wrong, but I feel a bit rude tone.
Of course, If I had known how it worked, I would not have asked for help!My - wrong - idea was since I've already changed the content of the widget in the
paint()
function, now its size should be already adjusted, hence I returned thesizeHint()
of the modified widget.Clearly, this does not work. I also read the documentation, but it does not explain how to retrieve the new size of the widget:
Reimplements: QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const.
Returns the size needed by the delegate to display the item specified by index, taking into account the style information provided by option.
This function uses the view's QStyle to determine the size of the item.From what I understand it should be done internally, like when you have a standard text column and its size is correctly adjusted to the content, without the need to manually set the size.
So, please, can you help me to understand how it works and how I can retrieve the new size of the widget after changing its content? I guess I have to check the new size inside the
paint()
function but I really cannot understand which member has this information. -
@Mark81
While you wait for a better answer.paint()
does not affectsizeHint()
. Rather, it assumes that the latter has returned the right size for the paint. If the paint goes outside the area returned as the size hint then you lose.QStyledItemDelegate::sizeHint()
receives the sameconst QModelIndex &index
as thepaint()
. Unlike your implementation, you must use that to pick out the specified item and repeat/share your code (generating your desired number of decimal places) to produce the string and measure its size to return that.You only change the text of each item (not other things to do with size). I note that
QStyledItemDelegate
has a virtual QString QStyledItemDelegate::displayText() method you can override. You might use that rather than yourpaint()
implementation since that seems simpler to me. I do not know whether that on its own would mean you do not need to implementsizeHint()
because Qt would calculate that for you from the string. Perhaps not, perhaps that would just result in a column width independent of its content. However it is worth a try? You say "since the QTableView does not adjust the column with to the content when calling resizeColumnsToContents()", but your content is only generated duringpaint()
and I don't see how that could affect resizing to content. If you try overridingdisplayText()
does resizing to content now work? -
@JonB now it's clear my fault. I understood the other way around.
Incidentally, my similar question on SO received the same hint about
displayText()
and I confirm it works without the need to overridesizeHint()
. In any case, I'm going to play a bit further with my current implementation in order to better understand the logic around these methods. Thanks! -
-
@Mark81
Yes, I think whateverdisplayText()
returns as text (default without your specific number of decimal places) is "measured" by Qt forsizeHint()
, and is simpler for your case thanpaint()
. The latter would be required if you wanted to affect other aspects of the output than only the text, e.g. you were drawing a box round it. But if the text is all you want to alter I would usedisplayText()
.