Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Update rect in delegate when changing content's size

Update rect in delegate when changing content's size

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 257 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mark81
    wrote on last edited by Mark81
    #1

    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 the opt.rect is not updated as well, since the QTableView does not adjust the column with to the content when calling resizeColumnsToContents():

    9ec01483-8b3a-4588-8a2d-e782a42e31ee-image.png

    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 the QTableView can correctly adjust the columns?

    1 Reply Last reply
    1
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Does your delegate return a suitable size hint ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Christian EhrlicherC M 2 Replies Last reply
      0
      • SGaistS SGaist

        Hi,

        Does your delegate return a suitable size hint ?

        Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @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

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          Does your delegate return a suitable size hint ?

          M Offline
          M Offline
          Mark81
          wrote on last edited by
          #4

          @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:

          a8f5e224-20dd-439d-b1ab-000a35b91d3e-image.png

          1 Reply Last reply
          0
          • Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Don't you think you should return something suitable to your requirements instead some default values?

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            M 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              Don't you think you should return something suitable to your requirements instead some default values?

              M Offline
              M Offline
              Mark81
              wrote on last edited by
              #6

              @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 the sizeHint() 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.

              JonBJ 1 Reply Last reply
              1
              • M Mark81

                @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 the sizeHint() 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.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Mark81
                While you wait for a better answer.

                paint() does not affect sizeHint(). 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 same const QModelIndex &index as the paint(). 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 your paint() implementation since that seems simpler to me. I do not know whether that on its own would mean you do not need to implement sizeHint() 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 during paint() and I don't see how that could affect resizing to content. If you try overriding displayText() does resizing to content now work?

                M 1 Reply Last reply
                4
                • JonBJ JonB

                  @Mark81
                  While you wait for a better answer.

                  paint() does not affect sizeHint(). 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 same const QModelIndex &index as the paint(). 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 your paint() implementation since that seems simpler to me. I do not know whether that on its own would mean you do not need to implement sizeHint() 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 during paint() and I don't see how that could affect resizing to content. If you try overriding displayText() does resizing to content now work?

                  M Offline
                  M Offline
                  Mark81
                  wrote on last edited by
                  #8

                  @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 override sizeHint(). 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!

                  JonBJ 1 Reply Last reply
                  1
                  • M Mark81 has marked this topic as solved on
                  • M Mark81

                    @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 override sizeHint(). 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!

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @Mark81
                    Yes, I think whatever displayText() returns as text (default without your specific number of decimal places) is "measured" by Qt for sizeHint(), and is simpler for your case than paint(). 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 use displayText().

                    1 Reply Last reply
                    1

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved