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.