Results 1 to 4 of 4

Thread: HTML rich text delegate and text centering/aligning, [code & pictures]

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

    Default HTML rich text delegate and text centering/aligning, [code & pictures]

    Simple example of the issue with a tableview:



    heres the code of the example, python 3 + pyqt4

    Qt Code:
    1. from PyQt4.QtCore import *
    2. from PyQt4.QtGui import *
    3. import sys
    4.  
    5. class My_Model_table(QAbstractTableModel):
    6. def __init__(self, table_data=[], parent=None):
    7. super().__init__()
    8. self.table_data = table_data
    9.  
    10. def rowCount(self, parent):
    11. return len(self.table_data)
    12.  
    13. def columnCount(self, parent):
    14. return 2
    15.  
    16. def data(self, index, role):
    17. if role == Qt.DisplayRole:
    18. value = self.table_data[index.row()]
    19. return value
    20. if role == Qt.TextAlignmentRole:
    21. return Qt.AlignCenter
    22.  
    23.  
    24. class My_table(QTableView):
    25. def __init__(self, parent=None):
    26. super().__init__()
    27. #rowHeight = self.fontMetrics().height()
    28. self.verticalHeader().setDefaultSectionSize(50)
    29.  
    30. def resizeEvent(self, event):
    31. width = event.size().width()
    32. self.setColumnWidth(0, width * 0.80)
    33.  
    34. class HTMLDelegate(QStyledItemDelegate):
    35. def __init__(self, parent=None):
    36. super().__init__()
    37. self.doc = QTextDocument(self)
    38.  
    39. def paint(self, painter, option, index):
    40. painter.save()
    41.  
    42. options = QStyleOptionViewItemV4(option)
    43. self.initStyleOption(options, index)
    44.  
    45. self.doc.setHtml(options.text)
    46. #options.text = ""
    47.  
    48. style = QApplication.style() if options.widget is None \
    49. else options.widget.style()
    50. style.drawControl(QStyle.CE_ItemViewItem, options, painter)
    51.  
    52. ctx = QAbstractTextDocumentLayout.PaintContext()
    53.  
    54. if option.state & QStyle.State_Selected:
    55. ctx.palette.setColor(QPalette.Text, option.palette.color(
    56. QPalette.Active, QPalette.HighlightedText))
    57.  
    58. textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
    59. #textRect.adjust(30, 5, 0, 0)
    60. painter.translate(textRect.topLeft())
    61. self.doc.documentLayout().draw(painter, ctx)
    62.  
    63. painter.restore()
    64.  
    65. def sizeHint(self, option, index):
    66. return QSize(self.doc.idealWidth(), self.doc.size().height())
    67.  
    68. if __name__ == '__main__':
    69. app = QApplication(sys.argv)
    70. data = ['1', '2', '<b>3</b>', '4', '5']
    71. main_list = My_table()
    72. main_list.setItemDelegate(HTMLDelegate())
    73. main_list.setModel(My_Model_table(data))
    74. main_list.show()
    75. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

    The delegate is something put together from the stackoverflow questions and googling around, I commented out line #46 that would normally hide the plain text, leaving only the desired rich html tag aware text.
    Also if you would remove aligning center at the lines #20 and #21 and custom row height at the line #27 and #28 it would look like this:



    What I am trying to point out by this, is that theres something affecting the plaintext by default, even without calling align on it, while this mechanism that vertically centers plaintext ignores the rich text.

    Now, I know I can move the text around by pixels with relative to its position by adjusting the text rectangle, commented out code at line #59 demonstrating this, but it needs to be done relative to the cell and text size to center correctly, and that I am not sure how I can do, where to get all the informations to do this correctly.
    Also I personally, I am not actually looking for horizontal center align, what I am looking for is the vertical align that would be as good as normal plain text allowing me to control row height and text staying centered across various desktop environments. Playing around with align and row height showed the issue for what it is - a positioning issue, rather than some font issue or something else.

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

    Default Re: HTML rich text delegate and text centering/aligning, [code & pictures]

    as I said I am looking only for vertical align... well I dug in a little and after testing and trying around I found a way, though theres need to be use of a constant.

    height of the table cell = option.rect.height()
    height of the font = options.fontMetrics.height()

    now normally this would be all we need.
    We subtract the font height from the rows height and we got the empty space left, which when divided by two would give us the equal margins when text is centered.
    so vertically interested only, 0 + height of one that margin gives us the position where the text should start so that empty space behind it, is also the same size
    unfortunately theres some shift in text position at the start. top left is not really 0,0 or at least visually its not. So we need to adjust it bit by a a specific amount of pixel = 4
    Qt Code:
    1. thefuckyourshitup_constant = 4
    2. margin = (option.rect.height() - options.fontMetrics.height()) // 2
    3. margin = margin - thefuckyourshitup_constant
    4. textRect.setTop(textRect.top()+margin)
    To copy to clipboard, switch view to plain text mode 
    if the code above is pasted in the example code, between 59 and 60 lines, you can see it in action, and working when you change the height of the rows at the line #28



    Its probably not the most ideal solution, maybe theres something more elegant as it can be seen its not a 100% center, but I tested it on gnome, kde, openbox and i3, and its close enough I guess

  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,620
    Thanks
    13
    Thanked 1,592 Times in 1,520 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: HTML rich text delegate and text centering/aligning, [code & pictures]

    Can you call blockBoundingRect() or documentSize() to get the size of the text block you have created and then position it vertically at the correct position?

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

    Default Re: HTML rich text delegate and text centering/aligning, [code & pictures]

    OP here after a long long time

    heres the fix that I used after all, sorry its been a long time, dont remember all the details but it works mostly

    Qt Code:
    1. from PyQt5.QtCore import *
    2. from PyQt5.QtGui import *
    3. from PyQt5.QtWidgets import *
    4.  
    5. import sys
    6.  
    7. class My_Model_table(QAbstractTableModel):
    8. def __init__(self, table_data=[], parent=None):
    9. super().__init__()
    10. self.table_data = table_data
    11.  
    12. def rowCount(self, parent):
    13. return len(self.table_data)
    14.  
    15. def columnCount(self, parent):
    16. return 2
    17.  
    18. def data(self, index, role):
    19. if role == Qt.DisplayRole:
    20. value = self.table_data[index.row()]
    21. return value
    22. if role == Qt.TextAlignmentRole:
    23. return Qt.AlignCenter
    24.  
    25.  
    26. class My_table(QTableView):
    27. def __init__(self, parent=None):
    28. super().__init__()
    29. #rowHeight = self.fontMetrics().height()
    30. self.verticalHeader().setDefaultSectionSize(50)
    31.  
    32. def resizeEvent(self, event):
    33. width = event.size().width()
    34. self.setColumnWidth(0, width * 0.80)
    35.  
    36. class HTMLDelegate(QStyledItemDelegate):
    37. def __init__(self, parent=None):
    38. super().__init__()
    39. self.doc = QTextDocument(self)
    40.  
    41. def paint(self, painter, option, index):
    42. painter.save()
    43.  
    44. options = QStyleOptionViewItem(option)
    45.  
    46. self.initStyleOption(options, index)
    47. self.doc.setHtml(options.text)
    48. #options.text = ""
    49.  
    50. style = QApplication.style() if options.widget is None \
    51. else options.widget.style()
    52. style.drawControl(QStyle.CE_ItemViewItem, options, painter)
    53.  
    54. ctx = QAbstractTextDocumentLayout.PaintContext()
    55.  
    56. if option.state & QStyle.State_Selected:
    57. ctx.palette.setColor(QPalette.Text, option.palette.color(
    58. QPalette.Active, QPalette.HighlightedText))
    59. else:
    60. ctx.palette.setColor(QPalette.Text, option.palette.color(
    61. QPalette.Active, QPalette.Text))
    62.  
    63. textRect = style.subElementRect(
    64. QStyle.SE_ItemViewItemText, options)
    65.  
    66. if index.column() != 0:
    67. textRect.adjust(5, 0, 0, 0)
    68.  
    69. thefuckyourshitup_constant = 4
    70. margin = (option.rect.height() - options.fontMetrics.height()) // 2
    71. margin = margin - thefuckyourshitup_constant
    72. textRect.setTop(textRect.top() + margin)
    73.  
    74. painter.translate(textRect.topLeft())
    75. painter.setClipRect(textRect.translated(-textRect.topLeft()))
    76. self.doc.documentLayout().draw(painter, ctx)
    77.  
    78. painter.restore()
    79.  
    80. def sizeHint(self, option, index):
    81. return QSize(self.doc.idealWidth(), self.doc.size().height())
    82.  
    83. if __name__ == '__main__':
    84. app = QApplication(sys.argv)
    85. data = ['1', '2', '<b>3</b>', '4', '5']
    86. main_list = My_table()
    87. main_list.setItemDelegate(HTMLDelegate())
    88. main_list.setModel(My_Model_table(data))
    89. main_list.show()
    90. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QTextEdit with html - rich text issue
    By kuku83 in forum Qt Programming
    Replies: 1
    Last Post: 23rd August 2012, 11:34
  2. QTabbar with rich text / html tab text
    By Berryblue031 in forum Qt Programming
    Replies: 1
    Last Post: 21st May 2012, 09:46
  3. Replies: 1
    Last Post: 6th December 2011, 22:44
  4. how to use html tags(rich text) in QTableWidgetHeaderItem
    By ansmehta in forum Qt Programming
    Replies: 0
    Last Post: 13th December 2010, 10:20
  5. QWidget pixmap AFTER displaying html ("rich text")
    By gavrilo princep in forum Newbie
    Replies: 0
    Last Post: 17th July 2007, 01:59

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.