from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QHeaderView, QVBoxLayout, QWidget, QApplication
from PyQt5.QtCore import Qt


class GroupedHeaderTable(QTableWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setColumnCount(8)
        self.setRowCount(5)

        # Top level header labels
        top_level_headers = ["Group 1", "Group 1", "Group 2", "Group 2", "Group 3", "Group 3", "Group 3", "Group 4"]

        # Second level header labels
        header_labels = ["A", "B", "C", "D", "E", "F", "G", "H"]

        self.setHorizontalHeaderLabels(header_labels)

        # Custom QHeaderView for grouping headers
        self.horizontalHeader().setSectionsClickable(False)
        self.verticalHeader().setSectionsClickable(False)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Create top level headers using a QTableWidget as overlay
        self.topHeader = QTableWidget(1, self.columnCount(), self)
        self.topHeader.setHorizontalHeaderLabels(top_level_headers)
        self.topHeader.horizontalHeader().setSectionsClickable(False)
        self.topHeader.verticalHeader().setSectionsClickable(False)
        self.topHeader.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.topHeader.setEditTriggers(QTableWidget.NoEditTriggers)
        self.topHeader.setFixedHeight(30)
        self.topHeader.move(0, self.horizontalHeader().height())
        self.topHeader.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.topHeader.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # Synchronize scrollbars
        self.horizontalScrollBar().valueChanged.connect(self.topHeader.horizontalScrollBar().setValue)
        self.topHeader.horizontalScrollBar().valueChanged.connect(self.horizontalScrollBar().setValue)


class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.table = GroupedHeaderTable(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.table)
        self.setLayout(layout)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    window = Example()
    window.resize(800, 600)
    window.show()
    sys.exit(app.exec_())
