I am using a custom header based on QHeaderView to create column labels that span multiple columns. The column labels are themselves QLabel objects. I can correctly resize the column labels when a column is resized. However, it is unclear how to reposition the labels when the table is horizontally scrolled. Currently the custom header labels remain stationary. Below is a working example:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
COL_LEN = 4
class CustomHeader(QHeaderView):
def __init__(self, orientation, top_text, parent=None):
QHeaderView.__init__(self, orientation, parent=None)
self.sectionResized.connect(self.handleSectionResized)
self.top_text = top_text
self.top_labels = list()
self.setFixedHeight(20)
def handleSectionResized(self, i):
# print('Resizing')
self.adjustPositions()
def showEvent(self, event):
ncol = self.count()
ntop = len(self.top_text)
for i in range(ntop):
text, start_col, span = self.top_text[i]
print(self.top_text[i])
label = QLabel(text, self)
label.setStyleSheet("font-weight:bold;background-color: gray;border-right: 1px solid white;")
label.setAlignment(Qt.AlignCenter)
self.top_labels.append(label)
label.show()
self.adjustPositions()
return super().showEvent(event)
def adjustPositions(self):
ntop = len(self.top_text)
for i in range(ntop):
text, start_col, span = self.top_text[i]
label = self.top_labels[i]
span_size = self.getSpanSize(start_col, span)
geom = QRect(
self.sectionViewportPosition(start_col),
0, #place at top
span_size,
self.height(),
)
label.setGeometry(geom)
def getSpanSize(self, index, span):
span_size = 0
for i in range(index, index+span):
span_size += self.sectionSize(i)
return span_size
class MyTable(QTableWidget):
def __init__(self, nrow, child_list, symbol, parent=None):
nchild = len(child_list)
ncol = (COL_LEN+1)*nchild + 1
super().__init__(nrow, ncol, parent=parent)
top_labels = self.create_label_info(symbol, child_list)
self.verticalHeader().hide()
self.setHorizontalHeaderLabels([''] * self.columnCount()) #uncomment to see column headers moving correctly
self.header = CustomHeader(Qt.Horizontal, top_labels, self)
self.setHorizontalHeader(self.header)
def create_label_info(self, symbol, child_list):
top_labels = list()
top_labels.append((symbol, 0,1))
n = 2
for e in child_list :
top_labels.append((e, n, COL_LEN))
n += COL_LEN + 1
return top_labels
class DebugWindow(QMainWindow):
def __init__(self):
super(DebugWindow, self).__init__()
self.table = MyTable(10, ['Child 1', 'Child 2'], 'Class')
layout = QVBoxLayout()
layout.addWidget(self.table)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DebugWindow()
window.show()
sys.exit(app.exec())