PySide – PyQt: ¿Cómo hacer que el ancho de la columna QTableWidget se establezca como proporción del espacio disponible?

Estoy desarrollando una aplicación informática con PySide y estoy usando QTableWidget. Digamos que mi tabla tiene 3 columnas, pero los datos que contienen son muy diferentes, como (para cada fila) una oración larga en la primera columna, luego números de 3 dígitos en las dos últimas columnas. Me gustaría cambiar el tamaño de mi tabla para ajustar su tamaño a los datos , o al menos poder establecer los tamaños de columna en (digamos) 70/15/15% del espacio disponible .

Cuál es la mejor manera de hacer esto ?

He intentado table.horizontalHeader().setResizeMode(QHeaderView.Stretch) después de leer esta pregunta pero hace 3 columnas del mismo tamaño.

También probé table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) gracias al comentario de Fabio , pero no llena todo el espacio disponible según sea necesario.

Ninguno de los documentos Interactive , Fixed , ResizeToContents y ResizeToContents de la documentación de QHeaderView parece darme lo que necesito (vea la segunda edición).

Cualquier ayuda sería apreciada, ¡incluso si es para Qt / C ++ ! Muchas gracias.


EDIT: Encontré una especie de solución alternativa pero aún no es lo que estoy buscando:

 header = table.horizontalHeader() header.setResizeMode(QHeaderView.ResizeToContents) header.setStretchLastSection(True) 

Sería mejor si existiera un método setStretchFirstSection , pero desafortunadamente no parece haber uno.


EDIT 2:

Lo único que se puede modificar en la tabla es la última columna, el usuario puede ingresar un número en ella. Las flechas rojas indican lo que me gustaría tener.

Esto es lo que pasa con Stretch Tramo

ResizeToContents es lo que pasa con ResizeToContents ResizeToContents

Esto se puede resolver configurando el modo de cambio de tamaño para cada columna. La primera sección debe extenderse para ocupar el espacio disponible, mientras que las dos últimas secciones simplemente cambian el tamaño de su contenido:

PyQt4:

 header = self.table.horizontalHeader() header.setResizeMode(0, QtGui.QHeaderView.Stretch) header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents) header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents) 

PyQt5:

 header = self.table.horizontalHeader() header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) 

PyQt4

 header = self.table.horizontalHeader() header.setResizeMode(0, QtGui.QHeaderView.Stretch) header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents) header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents) header.setResizeMode(3, QtGui.QHeaderView.Stretch) 

PyQt5

 header = self.table.horizontalHeader() header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch) 

Puede hacer esto con QItemDelegates o QStyledItemDelegates . Si desea cambiar el tamaño a los contenidos y tener estiramiento automático, deberá elegir qué columna es la columna “estirar”.

 class ResizeDelegate(QStyledItemDelegate): def __init__(self, table, stretch_column, *args, **kwargs): super(ResizeDelegate, self).__init__(*args, **kwargs) self.table = table self.stretch_column = stretch_column def sizeHint(self, option, index): size = super(ResizeDelegate, self).sizeHint(option, index) if index.column() == self.stretch_column: total_width = self.table.viewport().size().width() calc_width = size.width() for i in range(self.table.columnCount()): if i != index.column(): option_ = QtGui.QStyleOptionViewItem() index_ = self.table.model().index(index.row(), i) self.initStyleOption(option_, index_) size_ = self.sizeHint(option_, index_) calc_width += size_.width() if calc_width < total_width: size.setWidth(size.width() + total_width - calc_width) return size ... table = QTableWidget() delegate = ResizeDelegate(table, 0) table.setItemDelegate(delegate) ... # Add items to table table.resizeColumnsToContents() 

Puede configurar el modo de ResizeToContents tamaño en ResizeToContents , o si desea que el usuario pueda ajustar el ancho de la columna según sea necesario, simplemente llame a resizeColumnsToContents manualmente después de realizar cambios en los elementos de la tabla.

También es posible que deba modificarse un poco los cálculos de ancho debido a los márgenes y el relleno entre columnas (como agregar un píxel o dos al calculated_width de cada columna para tener en cuenta el borde de la celda).

Como se mencionó anteriormente, puede hacer esto configurando el modo de cambio de tamaño de cada columna. Sin embargo, si tiene muchas columnas, esto puede ser una gran cantidad de código. ¡La forma en que lo hago es establecer el modo de tamaño “general” en “ResizeToContent” y luego en una (o más) columnas en “Estirar”!

Aquí está el código:

PyQt4:

 header = self.table.horizontalHeader() header.setResizeMode(QtGui.QHeaderView.ResizeToContents) header.setResizeMode(0, QtGui.QHeaderView.Stretch) 

PyQt5:

 header = self.table.horizontalHeader() header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)