3

I wish to make horizontal header cells in a QTableView display text from top to bottom (i.e., vertically), how can I do this?

Example PyQt5 app which displays a QTableView with a horizontal header showing text in the normal direction:

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys

class TableModel(QAbstractTableModel):
    def __init__(self, parent):
        super(TableModel, self).__init__(parent)

    def headerData(self, section, orientation, role):
        if orientation != Qt.Horizontal:
            return
        if role != Qt.DisplayRole:
            return

        return 'Header Data'

    def data(self, index, role):
        if role != Qt.DisplayRole:
            return

        return 'Row Data'

    def rowCount(self, parent):
        return 1

    def columnCount(self, parent):
        return 1


class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)

        view = QTableView(main_widget)
        view.horizontalHeader().setVisible(True)
        view.verticalHeader().setVisible(False)
        layout.addWidget(view)
        model = TableModel(view)
        view.setModel(model)
        view.resizeColumnsToContents()

app = QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
aknuds1
  • 65,625
  • 67
  • 195
  • 317

2 Answers2

3

Simple use of delegate will not work here.

You need to subclass QHeaderView and override paintSection.
In implementation of it you need:

  • rotate and translate painter
  • calculate new rectange which wil take into acount above transformation
  • call old implementation of paintSection with new values
  • restore painter state (reverse transformation).
Marek R
  • 32,568
  • 6
  • 55
  • 140
2

The easy solution is to insert newlines between each character in the text of header cells (see the model's headerData method):

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys

class TableModel(QAbstractTableModel):
    def __init__(self, parent):
        super(TableModel, self).__init__(parent)

    def headerData(self, section, orientation, role):
        if orientation != Qt.Horizontal:
            return
        if role != Qt.DisplayRole:
            return

        # Make text appear flowing downwards
        return '\n'.join([x for x in 'Header Data']).replace(' ', '')

    def data(self, index, role):
        if role != Qt.DisplayRole:
            return

        return 'Row Data'

    def rowCount(self, parent):
        return 1

    def columnCount(self, parent):
        return 1


class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)

        view = QTableView(main_widget)
        view.horizontalHeader().setVisible(True)
        view.verticalHeader().setVisible(False)
        layout.addWidget(view)
        model = TableModel(view)
        view.setModel(model)
        view.resizeColumnsToContents()

app = QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
aknuds1
  • 65,625
  • 67
  • 195
  • 317