Vertical and horizontal headers are frozen by default when using the scrollbars if the table is not visible. I would like the scroll to apply to the headers as well, so when scrolling, they are not visible at all time.
Here is the example:
import string
import random
from typing import Optional
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QTableWidget, QWidget, QAbstractItemView, QHeaderView, QTableWidgetItem, QHBoxLayout, \
QApplication
class DataTable(QTableWidget):
# region Constructor
def __init__(self, parent: Optional[QWidget] = None):
super(DataTable, self).__init__(parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.setSelectionBehavior(QAbstractItemView.SelectItems)
self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.horizontalHeader().setTextElideMode(Qt.ElideMiddle)
for j in range(20):
if self.columnCount() <= j:
self.insertColumn(j)
for i in range(20):
if self.rowCount() <= i:
self.insertRow(i)
self.setItem(i, j, QTableWidgetItem('Hello'))
word = ''.join(random.choice(string.ascii_letters) for _ in range(6))
self.setHorizontalHeaderLabels([str(word) for i in range(self.columnCount())])
self.setVerticalHeaderLabels([str(word) for i in range(self.rowCount())])
if __name__ == '__main__':
app = QApplication()
widget = QWidget()
widget.resize(400, 600)
layout = QHBoxLayout(widget)
layout.addWidget(DataTable())
widget.show()
app.exec()
This is how it looks (see scrollbar is at the right):
How i'd like to look (basically the horizontal and vertical headers should move with the scroll):
To anyone interested, I the code below works. So I basically wrapped the QTableWidget in a QScrollArea, disabled the scrollbars from the QTableWidget and updated the minimum size.
import string
import random
from typing import Optional
from PySide6.QtCore import Qt, QSize
from PySide6.QtWidgets import QTableWidget, QWidget, QAbstractItemView, QHeaderView, QTableWidgetItem, QHBoxLayout, \
QApplication, QScrollArea
class DataTable(QScrollArea):
# region Constructor
def __init__(self, parent: Optional[QWidget] = None):
super(DataTable, self).__init__(parent)
self.setWidget(DataTableWidget(self))
self.setWidgetResizable(True)
class DataTableWidget(QTableWidget):
def __init__(self, parent: Optional[QWidget] = None):
super(DataTableWidget, self).__init__(parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.setSelectionBehavior(QAbstractItemView.SelectItems)
self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.horizontalHeader().setTextElideMode(Qt.ElideMiddle)
self.setSizeAdjustPolicy(QAbstractItemView.AdjustToContents)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
for j in range(20):
if self.columnCount() <= j:
self.insertColumn(j)
for i in range(20):
if self.rowCount() <= i:
self.insertRow(i)
self.setItem(i, j, QTableWidgetItem('Hello'))
word = ''.join(random.choice(string.ascii_letters) for _ in range(6))
self.setHorizontalHeaderLabels([str(word) for i in range(self.columnCount())])
self.setVerticalHeaderLabels([str(word) for i in range(self.rowCount())])
self.setMinimumSize(self.get_table_widget_size())
def get_table_widget_size(self):
w = self.verticalHeader().width() + 4 # +4 seems to be needed
for i in range(self.columnCount()):
w += self.columnWidth(i) # seems to include gridline (on my machine)
h = self.horizontalHeader().height() + 4
for i in range(self.rowCount()):
h += self.rowHeight(i)
return QSize(w, h)
if __name__ == '__main__':
app = QApplication()
widget = QWidget()
widget.resize(400, 600)
layout = QHBoxLayout(widget)
layout.addWidget(DataTable())
widget.show()
app.exec()