I want to proportionally change the column width of all columns in a QTableView widget, so that each column has the same width regardless of the data. For example, if a table has three columns, each column should always have a width of one third of the available horizontal space - and the width should be automatically updated whenever the dialog is resized by the user.
So far I've only managed to resize columns to their contents, which is not what I want. Here's the code I've got so far:
main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>329</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTableView" name="tableView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="btnPopulate">
<property name="text">
<string>Populate</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>btnPopulate</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
from PyQt5 import uic
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QDialog, QApplication, QHeaderView
class GUI(QDialog):
def __init__(self):
super(GUI, self).__init__()
dirname = os.path.dirname(os.path.abspath(__file__))
uic.loadUi(os.path.join(dirname,'main.ui'), self)
# button
self.btnPopulate.clicked.connect(self.populate)
# table model
self.header = ['col1', 'col2', 'col3']
self.QSModel = QStandardItemModel()
self.QSModel.setColumnCount(3)
self.QSModel.setHorizontalHeaderLabels(self.header)
# table view
self.tableView.setModel(self.QSModel)
self.tableView.setWordWrap(True)
self.tableView.horizontalHeader().setStretchLastSection(False)
def populate(self):
self.longtext = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac tellus nunc. Phasellus imperdiet leo metus, et gravida lacus. Donec metus ligula, elementum at pellentesque pellentesque, suscipit ac nunc.'''
row = self.QSModel.rowCount()
for x in range(7):
self.QSModel.insertRow(row)
self.QSModel.setData(self.QSModel.index(row, 0), 'Lorem ipsum')
self.QSModel.setData(self.QSModel.index(row, 1), self.longtext)
self.QSModel.setData(self.QSModel.index(row, 2), 'Lorem ipsum')
self.tableView.resizeColumnsToContents()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = GUI()
window.show()
sys.exit(app.exec_())
I've got the following questions:
setWordWrap(True)
wrap the text?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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With