Columns Auto-Resize to Size of Qtableview

Columns auto-resize to size of QTableView

There is a header flag to ensure that the QTableView's last column fills up its parent if resized. You can set it like so:

table_view->horizontalHeader()->setStretchLastSection(true);

However, that does not resize the other columns proportionately. If you want to do that as well, you could handle it inside the resizeEvent of your parent thusly:

void QParent::resizeEvent(QResizeEvent *event) {
table_view->setColumnWidth(0, this->width()/3);
table_view->setColumnWidth(1, this->width()/3);
table_view->setColumnWidth(2, this->width()/3);

QMainWindow::resizeEvent(event);
}

QParent class is subclass of QMainWindow.

Auto-resize columns of QTableView programmatically

Thanks to @Scheff, my question is answered.

The solution is to use resizeColumnToContent() to one of the columns which has not the stretch resize mode. Each other will be updated.

Edit : This solution works only when the column on which you call resizeColumnToContent() has to change its width. Otherwise you have to call resizeColumnToContent(int column) on each other.

Qt QTableView resize to fit content

Ok, I figure it out.

Reimplementing the resizeEvent will do the trick.

    def resizeEvent(self, event):
super(Table, self).resizeEvent(event)
height = self.horizontalHeader().height()
for row in range(self.model().rowCount()):
height += self.rowHeight(row)

if self.horizontalScrollBar().isVisible():
height += self.horizontalScrollBar().height()
self.setMaximumHeight(height + 2)

I'm changing the height of QTableView. I'm including height of horizontal header + height of all rows + height of horizontalScrollBar if it is visible.

How to proportionally adjust column widths in a QTableView?

This can be achieved by setting the section resize mode. To get equal column widths:

self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

To wrap the contents vertically:

self.tableView.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)

There is no need to call resizeToContents, setWordWrap or setStretchLastSection. Calling setWordWrap(False) will switch to eliding the text on the right, rather than wrapping.

Note that since the row/column resizing is done automatically, the sizes can no longer be changed by the user or programmatically.

How to make sure columns in QTableView are resized to the maximum

I managed to find a workaround for this issue, you just need to hide the table before calling resizeColumnsToContents().

For an example:

tableResult->setVisible(false);
tableResult->resizeColumnsToContents();
tableResult->setVisible(true);

QTableWidget column resize

You must set the setSectionResizeMode(index, mode) of the specific section of the horizontal header.

    self.table1.horizontalHeader().setSectionResizeMode( 
1, QtWidgets.QHeaderView.Stretch)

QTableView columns - can't set small width

You can try setting the minimum section size to zero for the horizontal header, this way:

tv1->horizontalHeader()->setMinimumSectionSize(0);

(Docs here).

How to auto stretch QTableView columns and keep them being adjustable

so here is a little trick I came up with. I modified the resize event of MyWindow to resize your QTableWidget.

class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)

self.tableModel=Model(self) #Set the model as part of your class to access it in the event handler

self.view=QTableView(self)
self.view.setModel(self.tableModel) #Modified here too
self.view.horizontalHeader().setResizeMode(QHeaderView.Interactive) #Mode set to Interactive to allow resizing

hideButton=QPushButton('Hide Column')
hideButton.clicked.connect(self.hideColumn)

unhideButton=QPushButton('Unhide Column')
unhideButton.clicked.connect(self.unhideColumn)

layout = QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(hideButton)
layout.addWidget(unhideButton)
self.setLayout(layout)

def hideColumn(self):
self.view.model().setColumnCount(1)

def unhideColumn(self):
self.view.model().setColumnCount(10)

#Added a reimplementation of the resize event
def resizeEvent(self, event):
tableSize = self.view.width() #Retrieves your QTableView width
sideHeaderWidth = self.view.verticalHeader().width() #Retrieves the left header width
tableSize -= sideHeaderWidth #Perform a substraction to only keep all the columns width
numberOfColumns = self.tableModel.columnCount() #Retrieves the number of columns

for columnNum in range( self.tableModel.columnCount()): #For each column
self.view.setColumnWidth(columnNum, int(tableSize/numberOfColumns) ) #Set the width = tableSize / nbColumns
super(MyWindow, self).resizeEvent(event) #Restores the original behaviour of the resize event

The only downfall is that the scrollbar is flicking. I think this can be solved with some adjustment.

Update:
Get a cleaner look when resizing, no more flicking, disabled the scrollbar.

Modified initialization of the QTableView:

self.view=QTableView(self) 
self.view.setModel(self.tableModel)
self.view.horizontalHeader().setResizeMode(QHeaderView.Interactive)
#Added these two lines
self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.horizontalHeader().setStretchLastSection(True)

Modified resizeEvent:

def resizeEvent(self, event):
super(MyWindow, self).resizeEvent(event)
tableSize = self.view.width()
sideHeaderWidth = self.view.verticalHeader().width()
tableSize -= sideHeaderWidth
numberOfColumns = self.tableModel.columnCount()

remainingWidth = tableSize % numberOfColumns
for columnNum in range( self.tableModel.columnCount()):
if remainingWidth > 0:
self.view.setColumnWidth(columnNum, int(tableSize/numberOfColumns) + 1 )
remainingWidth -= 1
else:
self.view.setColumnWidth(columnNum, int(tableSize/numberOfColumns) )

How do I resize QTableView so that the area is not scrolled anymore

What you could do is calculate your tableview columns widths according to the data they have (or you can just call resizeColumnToContents for each column to size it to its content). Then change the tableview width to be equal or more then total width of columns + vertical header if shown. You would also need to track model changes and adjust your tableview width + if horizontal header is shown you can track columns resize events and adjust them again. Below is some sample code for this:

initialization:

// add 3 columns to the tableview control
tableModel->insertColumn(0, QModelIndex());
tableModel->insertColumn(1, QModelIndex());
tableModel->insertColumn(2, QModelIndex());
...
// switch off horizonatal scrollbar; though this is not really needed here
ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// adjust size; see code below
adjustTableSize();
// connect to the horizontal header resize event (non needed if header is not shown)
connect(ui->tableView->horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this,
SLOT(updateSectionWidth(int,int,int)));
// connect to the model's datachange event
connect(ui->tableView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(dataChanged(QModelIndex,QModelIndex)));

adjust tableview size:

void MainWindow::adjustTableSize()
{
ui->tableView->resizeColumnToContents(0);
ui->tableView->resizeColumnToContents(1);
ui->tableView->resizeColumnToContents(2);

QRect rect = ui->tableView->geometry();
rect.setWidth(2 + ui->tableView->verticalHeader()->width() +
ui->tableView->columnWidth(0) + ui->tableView->columnWidth(1) + ui->tableView->columnWidth(2));
ui->tableView->setGeometry(rect);
}

process model change

void MainWindow::dataChanged(const QModelIndex &topLeft, const QModelIndex   &bottomRight)
{
adjustTableSize();
}

process horizontal header resize

void MainWindow::updateSectionWidth(int logicalIndex, int, int newSize)
{
adjustTableSize();
}

hope this helps, regards



Related Topics



Leave a reply



Submit