Search code examples
pyqt5pyside2pyside6

Remove default numbers from QHeaderView when using a custom label in the header


I am attempting to customize a QHeaderView in order to create custom labels that span two or more columns. In the code below, I have done this by placing a QLabel over the appropriate sections of the overall header. However, the default header numbering of the individual columns still appears as shown below. How can this be removed? I would prefer to do this without adding a background colour to each label.

enter image description here

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


class CustomHeader(QHeaderView):
    def __init__(self, orientation, labels, parent=None):
        QHeaderView.__init__(self, orientation, parent=None)
        self.sectionResized.connect(self.handleSectionResized)
        self.label_text = labels
        self.labels = list()
        self.setFixedHeight(40)

    def handleSectionResized(self, i):
        start = self.visualIndex(i)
        stop = self.count()
        for i in range(start, stop):
            self.labels[i].setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i) - 5, self.height())
            self.labels[i].show()

    def showEvent(self, event):
        for i in range(len(self.label_text)):
            label = QLabel(self.label_text[i], self) 
            label.setAlignment(Qt.AlignCenter)
            widget = QWidget(self)
            vbox = QVBoxLayout()
            vbox.setSpacing(0)
            vbox.setContentsMargins(0,0,0,0)
            vbox.addWidget(label)
            widget.setLayout(vbox)
            widget.show()
            self.labels.append(widget)
        self.adjustPositions()
        return super().showEvent(event)


    def adjustPositions(self):
        for index, label in enumerate(self.labels):
            if index == 1 or index == 3:
                size = self.sectionSize(index)
                print(size)
                geom = QRect(
                    self.sectionViewportPosition(index),
                    0,
                    200,
                    self.height(),
                )
            else:
                size = self.sectionSize(index)
                print(size)
                geom = QRect(
                    self.sectionViewportPosition(index),
                    0,
                    self.sectionSize(index),
                    self.height(),
                )
            geom.adjust(2, 0, -2, 0)
            label.setGeometry(geom)


class MyTable(QTableWidget):
    def __init__(self, nrow, ncol, parent=None):
        super().__init__(nrow, ncol, parent=parent)
        self.verticalHeader().hide()
        self.setHorizontalHeaderLabels([])
        labels = ['One', 'Two', '', 'Three'] #, 'Four', 'Five']
        self.header = CustomHeader(Qt.Horizontal, labels, self)
        self.setHorizontalHeader(self.header)
        self.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        data = [
            [3, 20, 40, 25, 45],
            [5, 22, 42, 27, 47],
        ]
        for i in range(2):
            for j in range(5):
                item = QTableWidgetItem(str(data[i-2][j]))
                self.setItem(i, j, item)
                item.setBackground(Qt.white)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    table = MyTable(7, 5)
    table.show()
    sys.exit(app.exec())
    

Solution

  • You could change them the same way you would with the standard header.

    In your QTableWidget just call:

    self.setHorizontalHeaderLabels([""] * self.columnCount())
    

    For example:

    class MyTable(QTableWidget):
        def __init__(self, nrow, ncol, parent=None):
            super().__init__(nrow, ncol, parent=parent)
            self.verticalHeader().hide()
            self.setHorizontalHeaderLabels([])
            labels = ['One', 'Two', '', 'Three'] #, 'Four', 'Five']
            self.header = CustomHeader(Qt.Horizontal, labels, self)
            self.setHorizontalHeaderLabels([""] * self.columnCount())  # added this
            self.setHorizontalHeader(self.header)
            self.setSelectionBehavior(QAbstractItemView.SelectItems)
            self.setEditTriggers(QAbstractItemView.NoEditTriggers)