Как добавить объект QLabel в qheaderview? - PullRequest
1 голос
/ 30 июня 2019

необходимо добавить индекс в горизонтальный заголовок QTableWidget с QLabel, где html будет текстом QLabel.

1 Ответ

1 голос
/ 30 июня 2019

Вы должны создать QLabels, родительским объектом для которых является QHeaderView, и при необходимости обновить отображаемую информацию и ее геометрию:

from PyQt5 import QtCore, QtGui, QtWidgets


class HeaderProxyStyle(QtWidgets.QProxyStyle):
    def drawControl(self, element, option, painter, widget=None):
        if element == QtWidgets.QStyle.CE_Header:
            option.text = ""
        super(HeaderProxyStyle, self).drawControl(
            element, option, painter, widget
        )


class LabelHeaderView(QtWidgets.QHeaderView):
    def __init__(self, parent):
        super(LabelHeaderView, self).__init__(QtCore.Qt.Horizontal, parent)
        self.m_labels = []
        self.sectionResized.connect(self.adjustPositions)
        self.sectionCountChanged.connect(self.onSectionCountChanged)
        self.parent().horizontalScrollBar().valueChanged.connect(
            self.adjustPositions
        )
        proxy_style = HeaderProxyStyle(self.style())
        self.setStyle(proxy_style)

    @QtCore.pyqtSlot()
    def onSectionCountChanged(self):
        while self.m_labels:
            label = self.m_labels.pop()
            label.deleteLater()
        for i in range(self.count()):
            label = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)
            self.m_labels.append(label)
            self.update_data()
            self.adjustPositions()

    def setModel(self, model):
        super(LabelHeaderView, self).setModel(model)
        if self.model() is not None:
            self.model().headerDataChanged.connect(self.update_data)

    def update_data(self):
        option = QtWidgets.QStyleOptionHeader()
        self.initStyleOption(option)
        for i, label in enumerate(self.m_labels):
            text = self.model().headerData(
                i, self.orientation(), QtCore.Qt.DisplayRole
            )
            label.setText(str(text))
            pal = label.palette()
            bc = self.model().headerData(
                i, self.orientation(), QtCore.Qt.BackgroundRole
            )
            if bc is None:
                bc = option.palette.brush(QtGui.QPalette.Window)
            pal.setBrush(QtGui.QPalette.Window, bc)

            fc = self.model().headerData(
                i, self.orientation(), QtCore.Qt.ForegroundRole
            )
            if fc is None:
                fc = option.palette.brush(QtGui.QPalette.ButtonText)
            pal.setBrush(QtGui.QPalette.ButtonText, fc)

            label.setPalette(pal)

            textAlignment = self.model().headerData(
                i, self.orientation(), QtCore.Qt.TextAlignmentRole
            )
            if textAlignment is None:
                textAlignment = self.defaultAlignment()
            label.setAlignment(textAlignment)

    def updateGeometries(self):
        super(LabelHeaderView, self).updateGeometries()
        self.adjustPositions()

    @QtCore.pyqtSlot()
    def adjustPositions(self):
        for index, label in enumerate(self.m_labels):
            geom = QtCore.QRect(
                self.sectionViewportPosition(index),
                0,
                self.sectionSize(index),
                self.height(),
            )
            geom.adjust(2, 0, -2, 0)
            label.setGeometry(geom)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QTableWidget(10, 10)
    header = LabelHeaderView(w)
    w.setHorizontalHeader(header)

    header_labels = []
    for i in range(w.columnCount()):
        header_label = "<sub>%s</sub><b>Header</b><sup>%s</sup>" % (i, i)
        header_labels.append(header_label)
    w.setHorizontalHeaderLabels(header_labels)

    w.resize(320, 240)
    w.show()
    sys.exit(app.exec_())

enter image description here

...