2

Let's assume there is an attribute table of a vector layer which was opened with F6, see image below

input

With the code below I could set the minimum height and width of all cells in the attribute table.

from PyQt5.QtWidgets import QApplication, QTableView

attrTables = [d for d in QApplication.instance().allWidgets() if 'QgsAttributeTableDialog' in d.objectName()]

if len(attrTables): attrTables[0].findChildren(QTableView)[0].resizeColumnsToContents() attrTables[0].findChildren(QTableView)[0].resizeRowsToContents()

result_temp

However it is only temporal. After closing and opening the table, the height of each cell does not remain, only the width is maintained.

result_current

How can I make it permanent in height?


References:

Taras
  • 32,823
  • 4
  • 66
  • 137

1 Answers1

1

Conclusion

  • It is impossible to apply permanent changes to cells' height. It seems like resizeRowsToContents() works only partially. Because after closing the attribute table, rows won't preserve their dimension
  • It is possible to adjust column width both via PyQt and PyQGIS

Indeed, as was mentioned in a comment by @Matt, there is a setAttributeTableConfig() method of the QgsVectorLayer class:

This is a container for configuration of the attribute table.

The configuration is specific for one vector layer.

To get the width of a column one can try the attributeTableConfig() method.

Returns the attribute table configuration object.

This defines the appearance of the attribute table.

from qgis.utils import iface

layer = iface.activeLayer()

layer_attr_table_config = layer.attributeTableConfig() columns = layer_attr_table_config.columns()

for column in columns: if not column.hidden: print(f"Column '{column.name}' : {column.width}")

Nevertheless, it will show the default width which is -1.

Column 'osm_id' : -1
Column 'lastchange' : -1
Column 'code' : -1
Column 'fclass' : -1
Column 'geomtype' : -1
Column 'name' : -1
Column 'type' : -1
Column 'height' : -1
Column 'levels' : -1

More details can be found in QgsAttributeTableConfig class.

To change the width of a single column

It utilizes the setColumnWidth() and setAttributeTableConfig() methods

from qgis.core import QgsProject

def setting_one_column_width(layer_name: str, column_name: str, new_width: int): """ Changes the width of a single column in the layer :param layer_name: name of the layer :param column_name: name of the target column :param new_width: new column width in pixels """

layer = QgsProject.instance().mapLayersByName(layer_name)[0]
column_index = layer.fields().indexOf(column_name)

layer_attr_table_config = layer.attributeTableConfig()
layer_attr_table_config.setColumnWidth(column_index, new_width)

layer.setAttributeTableConfig(layer_attr_table_config)

return

setting_one_column_width('gis_osm_buildings', 'osm_id', 100)

To change the width of all columns

Based on @ThomasG77's answer. It uses the setColumns() and setAttributeTableConfig() methods

from qgis.core import QgsAttributeTableConfig, QgsProject

def setting_all_columns_widths(layer_name: str, new_width: int) -> None: """ Changes widths of all columns in the layer :param layer_name: name of the layer :param new_width: new column width in pixels """

layer = QgsProject.instance().mapLayersByName(layer_name)[0]

layer_attr_table_config = layer.attributeTableConfig()
columns_config = layer_attr_table_config.columns()

new_columns_config = []
new_layer_attr_table_config = QgsAttributeTableConfig()

for column in columns_config:
    new_column = layer_attr_table_config.ColumnConfig()
    new_column.hidden = column.hidden
    new_column.name = column.name
    new_column.type = column.type
    new_column.width = new_width
    new_columns_config.append(new_column)

new_layer_attr_table_config.setColumns(new_columns_config)

layer.setAttributeTableConfig(new_layer_attr_table_config)

return

setting_all_columns_widths('gis_osm_buildings', 100)

Keep in mind, that changes will be noticeable after closing and opening again the attribute table.

However, there are also several incompleteness in the above approaches:

  1. autosize functionality comes from PyQt
  2. it does not shrink rows, only columns

To autosize the width of all columns

Partially overlaps with @Joseph's and @MatthiasKuhn's answers. It applies the resizeColumnsToContents() method from the QTableView class.

from qgis.utils import iface
from qgis.core import QgsProject
from PyQt5.QtWidgets import QApplication, QTableView

def autosize_all_columns_widths(layer_name: str) -> None: """ Autosizes widths of all columns in the layer :param layer_name: name of the layer """

layer = QgsProject.instance().mapLayersByName(layer_name)[0]

all_widgets = QApplication.instance().allWidgets()
attribute_table_widgets = [widget for widget in all_widgets if "AttributeTable" in widget.objectName()]

if len(attribute_table_widgets) == 0:
    iface.showAttributeTable(layer)
    all_widgets = QApplication.instance().allWidgets()
    attribute_table_widgets = [widget for widget in all_widgets if "AttributeTable" in widget.objectName()]

for widget in attribute_table_widgets:
    if not widget.isWindow():
        if layer.name() in widget.objectName():
            table_view = widget.findChildren(QTableView)[0]
            table_view.resizeColumnsToContents()
            # table_view.resizeRowsToContents()
            widget.close()

return

autosize_all_columns_widths('gis_osm_buildings')


References:

Taras
  • 32,823
  • 4
  • 66
  • 137