Results 1 to 6 of 6

Thread: PyQt, Custom delegate for html format text causes jittery refreshing [GIF included]

  1. #1
    Join Date
    Apr 2015
    Posts
    20
    Thanks
    7
    Qt products
    Platforms
    Unix/X11

    Question PyQt, Custom delegate for html format text causes jittery refreshing [GIF included]

    Link to project's GitHub

    I am attempting to make an instant-as-you-type-file-search for linux inspired by Everything-search-engine.
    It's in PyQt5 and Python3. Week ago I got it in to pretty decent shape by my standard:



    Now for the last few days I was attempting to get the search term to appear bold in the results in the listview and for that I had to use delegate so that I can just use bold tags.
    I struggled through and got it somewhat working, without some decent understanding of how it works as I have not found much tutorial resources on the delegates in PyQt/PySide, just completed done things that I could observe and tinker around with.

    Now when its relatively done I observed visual degradation in quality when compared to the version without a delegate.

    Heres a gif of it in action showing first with the delegate and then without

    gfycat backup link

    I would describe it that the listview seems to have multiple empty frames where it shows nothing before content appears, which make it look like its its blinking.
    This does not appear when not using the delegate.


    Here is the code of the delegate in question:

    Qt Code:
    1. class HTMLDelegate(QStyledItemDelegate):
    2. def paint(self, painter, option, index):
    3. options = QStyleOptionViewItem(option)
    4. self.initStyleOption(options, index)
    5. style = QApplication.style() if options.widget is None \
    6. else options.widget.style()
    7.  
    8. doc = QTextDocument(self)
    9. doc.setHtml(options.text)
    10.  
    11. options.text = ""
    12. style.drawControl(QStyle.CE_ItemViewItem, options, painter)
    13.  
    14. ctx = QAbstractTextDocumentLayout.PaintContext()
    15.  
    16. if option.state & QStyle.State_Selected:
    17. ctx.palette.setColor(QPalette.Text, option.palette.color(
    18. QPalette.Active, QPalette.HighlightedText))
    19.  
    20. textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
    21. painter.save()
    22. painter.translate(textRect.topLeft())
    23. painter.setClipRect(textRect.translated(-textRect.topLeft()))
    24. doc.documentLayout().draw(painter, ctx)
    25.  
    26. painter.restore()
    27.  
    28. def sizeHint(self, option, index):
    29. options = QStyleOptionViewItem(option)
    30. self.initStyleOption(options, index)
    31.  
    32. doc = QTextDocument(self)
    33. doc.setDocumentMargin(1)
    34. doc.setHtml(options.text)
    35. return QSize(doc.idealWidth(), 23)
    To copy to clipboard, switch view to plain text mode 

    Is this solvable? Or is it the performance price for using custom delegate and theres just no way around it?

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,366
    Thanks
    36
    Thanked 1,537 Times in 1,488 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: PyQt, Custom delegate for html format text causes jittery refreshing [GIF include

    Have you tried reusing the QTextDocument?
    I.e. keeping it as a member of your delegate instance instead of creating a new one on every paint?

    Cheers,
    _

  3. #3
    Join Date
    Apr 2015
    Posts
    20
    Thanks
    7
    Qt products
    Platforms
    Unix/X11

    Default Re: PyQt, Custom delegate for html format text causes jittery refreshing [GIF include

    Thanks for the suggestion, I tried the code like this, but no change in behavior, it's still "blinking"

    Qt Code:
    1. class HTMLDelegate(QStyledItemDelegate):
    2. def __init__(self, parent=None):
    3. super(HTMLDelegate, self).__init__(parent)
    4. self.doc = QTextDocument(self)
    5.  
    6. def paint(self, painter, option, index):
    7. options = QStyleOptionViewItem(option)
    8. self.initStyleOption(options, index)
    9. style = QApplication.style()
    10.  
    11. self.doc.setHtml(options.text)
    12.  
    13. options.text = ""
    14. style.drawControl(QStyle.CE_ItemViewItem, options, painter)
    15.  
    16. ctx = QAbstractTextDocumentLayout.PaintContext()
    17.  
    18. if option.state & QStyle.State_Selected:
    19. ctx.palette.setColor(QPalette.Text, option.palette.color(
    20. QPalette.Active, QPalette.HighlightedText))
    21.  
    22. textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
    23. painter.save()
    24. painter.translate(textRect.topLeft())
    25. painter.setClipRect(textRect.translated(-textRect.topLeft()))
    26. self.doc.documentLayout().draw(painter, ctx)
    27.  
    28. painter.restore()
    29.  
    30. def sizeHint(self, option, index):
    31. options = QStyleOptionViewItem(option)
    32. self.initStyleOption(options, index)
    33.  
    34. self.doc.setDocumentMargin(1)
    35. self.doc.setHtml(options.text)
    36. return QSize(self.doc.idealWidth(), 23)
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,537
    Thanks
    13
    Thanked 1,576 Times in 1,505 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: PyQt, Custom delegate for html format text causes jittery refreshing [GIF include

    Try setting the clipping rectangle on the QPaintContext rather than the painter. You may find the layout engine can make a smarter choice of how to paint.

  5. The following user says thank you to ChrisW67 for this useful post:

    DoTheEvo (6th April 2015)

  6. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,366
    Thanks
    36
    Thanked 1,537 Times in 1,488 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: PyQt, Custom delegate for html format text causes jittery refreshing [GIF include

    Another potential slow down can be save/restore on a painter.
    It is often faster to just "undo" the changes, e.g. translate back to "undo" the translation.

    Cheers,
    _

  7. The following user says thank you to anda_skoa for this useful post:

    DoTheEvo (6th April 2015)

  8. #6
    Join Date
    Apr 2015
    Posts
    20
    Thanks
    7
    Qt products
    Platforms
    Unix/X11

    Default Re: PyQt, Custom delegate for html format text causes jittery refreshing [GIF include

    THANK YOU ALL FOR REPLYING!

    It was my bad at the very beginning
    I was doing setItemDelegate() on every keypress instead of just putting it there right after creating the listview

    All is well


Similar Threads

  1. Refreshing a Custom QwtScaleDraw
    By grantbj74 in forum Qwt
    Replies: 6
    Last Post: 28th March 2012, 05:20
  2. Replies: 1
    Last Post: 6th December 2011, 22:44
  3. Custom Delegate and Text Wrap
    By enlightened_j in forum Newbie
    Replies: 2
    Last Post: 17th September 2010, 06:21
  4. Threaded refreshing of a TreeView with custom model
    By CLRS530 in forum Qt Programming
    Replies: 4
    Last Post: 25th August 2009, 08:23
  5. Displaying picture included with html code
    By Djony in forum Qt Tools
    Replies: 1
    Last Post: 27th November 2006, 16:15

Tags for this Thread

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.