Can QTableWidget header text be vertical, but cell text horizontal?
-
wrote on 16 Jul 2020, 15:53 last edited by
I've got some QTableWidgets in my PyQt5 application where the cell content is short, but some of the cell headers are necessarily quite long.
Ideally, I would like to be able to render the header text vertically, but only in those columns that need it (most of the columns are fine), but leave all the actual table cell context in the standard horizontal orientation.
Is this something that Qt supports, or which can be done in PyQt5? I've read conflicting answers online about whether it's actually possible.
My current test code is below. It doesn't work, but I don't understand why, and whether it will ever work. If I comment out the
setItemDelegate
line then it works as a standard QTableWidget, but as soon as I attempt to add the delegate, it starts crashing.import sys from PyQt5 import QtGui, QtCore from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QGridLayout, QFrame, QDialog, \ QStyledItemDelegate class VerticalTextDelegate(QStyledItemDelegate): def __init__(self, parent): super(VerticalTextDelegate, self).__init__() def paint(self, painter, option, index): optionCopy = QtGui.QStyleOptionViewItem(option) rectCenter = QtCore.QPointF(QtCore.QRectF(option.rect).center()) painter.save() painter.translate(rectCenter.x(), rectCenter.y()) painter.rotate(-90.0) painter.translate(-rectCenter.x(), -rectCenter.y()) optionCopy.rect = painter.worldTransform().mapRect(option.rect) # Call the base class implementation super(VerticalTextDelegate, self).paint(painter, optionCopy, index) painter.restore() def sizeHint(self, option, index): val = QtGui.QSize(self.sizeHint(option, index)) return QtGui.QSize(val.height(), val.width()) class VerticalWidgetDialog(QDialog): def __init__(self, windowTitle): super().__init__() self.setWindowTitle(windowTitle) self.layout = QGridLayout(self) self.table = QTableWidget() rowCount, columnCount = 8, 6 self.table.setRowCount(rowCount) self.table.setColumnCount(columnCount) for c in range(0, columnCount): self.table.setHorizontalHeaderItem(c, QTableWidgetItem("Header" + str(c))) for r in range(0, rowCount): for c in range(0, columnCount): text = str(r) + ":" + str(c) self.table.setItem(r, c, QTableWidgetItem(text)) self.table.setItemDelegateForColumn(2, VerticalTextDelegate(self)) self.innerLayout = QGridLayout() self.innerLayoutFrame = QFrame() self.innerLayoutFrame.setLayout(self.innerLayout) self.innerLayout.addWidget(self.table) self.layout.addWidget(self.innerLayoutFrame, 0, 0) if __name__ == '__main__': app = QApplication(sys.argv) windowTitle = "Table header test" testDialog = VerticalWidgetDialog(windowTitle) testDialog.show() sys.exit(app.exec_())
The expected result I get without the
setItemDelegate
line:
but all attempts to make any of the header text vertical has so far failed.
-
Hi
The QHeaderView doesn't support Delegates sadly.
But you can subclass it and override
https://doc.qt.io/qt-5/qheaderview.html#paintSection
and paint the rotated text there.
Im sorry i don't have any samples for python. -
wrote on 17 Jul 2020, 06:09 last edited by
OK thanks, I'll look into the subclassing and see if it gives me any success.
1/3