Reputation: 55
If I have Table Like as mention Below,
And I want to do as below to squeeze all columns bear to minimum scrollbar size or without scrollbar,
In PyQt5 in QTableview how can I do align any content to center in cell and want to minimum scrollbar and if possible without scrollbar then also it is well good.
as like below image text are not align and I wish to do squeeze all columns as per image 1 and align text to center in PyQt5 in Python.
Upvotes: 0
Views: 788
Reputation: 48231
The trick is to use the Stretch
resize mode of the horizontal header, which ensures that all columns fit the available size of the view. The only problem comes from the minimumSectionSize()
, which by default is a value dependent on the font and the margin between the sort indicator and the text of each header section, so, even using Stretch, the columns wouldn't resize below that width.
By setting the minimum size to 0 we can prevent that behavior. Keep in mind, though, that even with not-so-narrow columns (under 16-18 pixels wide) you will not be able to see the header text at all, no matter if there could be enough space for the text to be shown: some space is always reserved to the header section separators and their margin.
About the text alignment, the standard approach is to use setTextAlignment
on each item. If you need to do that constantly, just use a subclass of QStandardItem that automatically sets its alignment after initialization.
from PyQt5 import QtCore, QtGui, QtWidgets
class FitTable(QtWidgets.QTableView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.horizontalHeader().setMinimumSectionSize(0)
def resizeEvent(self, event):
super().resizeEvent(event)
if not self.model() or not self.model().columnCount():
return
# the text can be completely hidden on very narrow columns if the
# elide mode is enabled; let's disable it for widths lower than
# the average width of 3 characters
colSize = self.viewport().width() // self.model().columnCount()
if colSize < self.fontMetrics().averageCharWidth() * 3:
self.setTextElideMode(QtCore.Qt.ElideNone)
else:
self.setTextElideMode(QtCore.Qt.ElideRight)
class CenteredItem(QtGui.QStandardItem):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setTextAlignment(QtCore.Qt.AlignCenter)
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QGridLayout(self)
self.table = FitTable()
layout.addWidget(self.table)
model = QtGui.QStandardItemModel()
self.table.setModel(model)
for row in range(5):
rowItems = []
for column in range(30):
# usually the text alignment is manually applied like this:
# item = QtGui.QStandardItem(str(column + 1))
#
# item.setTextAlignment(QtCore.Qt.AlignCenter)
#
# for convenience, I use a subclass that automatically does that
item = CenteredItem(str(column + 1))
rowItems.append(item)
model.appendRow(rowItems)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Upvotes: 2