Results 1 to 12 of 12

Thread: QItemDelegate, QTreeView and scrollbars

  1. #1
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default QItemDelegate, QTreeView and scrollbars

    Hello again!

    I have a custom delegate that inherits from QItemDelegate. When displayed into a QTreeView, the delegate renders fine. Except for one thing: if I reduce the viewing area, there is no scrollbars anymore:

    Before resizing:


    After resizing with the mouse (no scrollbars):


    For information, I reimplement the sizeHint method to override the delegate height (it works).

    I am guessing that I must inform the View that the delegate is that pixels wide, and that the view should scroll to display it. Am I looking at the right spot?

    Thanks again!

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QItemDelegate, QTreeView and scrollbars

    Delegate has no width. It is the view that tells the delegate the rectangle to paint on based on some conditions. One of them is the value returned by the sizeHint() method. So there are two things to remember:
    1. return proper values in sizeHint()
    2. don't draw outside the rectangle given to the delegate's paint() method by the view.

    Another thing to check is that you didn't turn off scrollbars manually using the view's properties.

  3. #3
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Ok I just found the problem why the scrollbars were not showing up. I have a stylesheet in my QTreeView widget that sets the background color. This seems to be a problem for the scrollbars:

    With stylesheet:


    Without stylesheet:


    Well that partly solves the problem Now back on it, the simplified problem is that the scrollbars are not in sync with the delegate width:

    See, the text is clipped:




    Delegate has no width. It is the view that tells the delegate the rectangle to paint on based on some conditions.One of them is the value returned by the sizeHint() method. So there are two things to remember:
    1. return proper values in sizeHint()
    2. don't draw outside the rectangle given to the delegate's paint() method by the view.
    Ok, so in the delegate's paint() method, I have to "clip" my painting to fit within the given option.rect rectangle?

    How does the View knows when to display a scrollbar?

    Is it normal that the given option.rect rectangle in sizeHint is set to x0,y0, and has a width of -1 and a height of 0?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QItemDelegate, QTreeView and scrollbars

    Quote Originally Posted by SiLiZiUMM View Post
    Ok, so in the delegate's paint() method, I have to "clip" my painting to fit within the given option.rect rectangle?
    Yes, that's the rectangle containing the index you are currently painting.

    How does the View knows when to display a scrollbar?
    It calculates the size of all items and compares them to the size of its viewport.

    Is it normal that the given option.rect rectangle in sizeHint is set to x0,y0, and has a width of -1 and a height of 0?
    Yes, it's an empty QRect.

  5. #5
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Ok now my delegate does not paint outside the option.rect in the paint() method. Still, no luck for the horizontal scrollbars.

    I tried to return a QSize(1000, 50); in sizeHint: the row height is really 50 pixels, but the width parameter does absolutely nothing.. I was thinking that sizeHint would be used to calculate the width of the item, and that the returned with would be used by the view.. guess I am wrong again?

    Also, after investigating a bit, sizeHint() is called when the item is expanded or collapsed, but not when the viewport size change...

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QItemDelegate, QTreeView and scrollbars

    What is the horizontalScrollBarPolicy of the view?

  7. #7
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Quote Originally Posted by wysota View Post
    What is the horizontalScrollBarPolicy of the view?
    The default policy (Qt::ScrollBarAsNeeded). In fact, if I choose the Qt::ScrollBarAlwaysOn policy, the scrollbars are greyed out until I reach the same point than the default policy : my text is clipped (and the QSize width of the delegate's returned sizeHint still have no effect)...


  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QItemDelegate, QTreeView and scrollbars

    Could you post the contents of your delegate?

  9. #9
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Sure, here's a simple version of my class (I removed the unneeded stuff for this problem, the following code reproduces the problem):

    sizeHint():
    Qt Code:
    1. QSize MyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const
    2. {
    3. // Override the default height
    4. QSize size(QItemDelegate::sizeHint(option, index));
    5. QFontMetrics fm(option.fontMetrics);
    6.  
    7. if(fm.height() > 16)
    8. {
    9. size.setHeight(fm.height() + 4);
    10. }
    11. else
    12. {
    13. size.setHeight(20);
    14. }
    15.  
    16. //return QSize(1000,50);
    17. return size;
    18. }
    To copy to clipboard, switch view to plain text mode 


    paint():
    Qt Code:
    1. void MyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    2. {
    3. painter->save();
    4.  
    5. // Useless stuff skipped...
    6.  
    7.  
    8. // Draw the content of the delegate
    9.  
    10. // Text rectangle
    11. // The text will be vertically centered.
    12. // If a context is available, the context will be displayed in bold, between brackets.
    13. QString text(index.data(Qt::DisplayRole).value<QString>());
    14. if(!index.parent().isValid()) // TODO: IF CONTEXT
    15. {
    16. text.append(" <b>(bold text)</b>"); // TODO: get the text from the model
    17. }
    18.  
    19. QTextDocument textDoc;
    20. textDoc.setHtml(text);
    21.  
    22. int textX = option.rect.x();
    23. int textY = (option.rect.height() - textDoc.size().height())/2 + option.rect.y();
    24.  
    25. // Set the text rectangle width (the smaller of the two will be used): either as wide as the text width, or as
    26. int textWidth = qMin<int>(textDoc.size().width(), option.rect.width());
    27. QRect textRect(textX, textY, textWidth, option.rect.height());
    28.  
    29. // Translate the painter to the position of the text rectangle in order to paint the QTextDocument
    30. // Then paint the text as HTML formatted text
    31. painter->save();
    32. painter->translate(textRect.topLeft());
    33. textDoc.drawContents(painter, textRect.translated(-textRect.topLeft()));
    34. painter->restore();
    35.  
    36.  
    37. painter->restore();
    38. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Oh by the way, my class inherits from QItemDelegate

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QItemDelegate, QTreeView and scrollbars

    Your sizeHint() implementation seems to be incorrect. If you use QTextDocument for rendering the data, you should also use it for checking the size needed to make the item fit.

  12. #12
    Join Date
    May 2007
    Posts
    20
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QItemDelegate, QTreeView and scrollbars

    Quote Originally Posted by wysota View Post
    Your sizeHint() implementation seems to be incorrect. If you use QTextDocument for rendering the data, you should also use it for checking the size needed to make the item fit.
    From my example, wouldn't return QSize(1000,50) in sizeHint force the view to display the item 1000pixels wide (which it does not if I return that size) and 50 pixels tall (which it does)?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.