I can suggest a PyQGIS approach to (1) adjust, (2) export, (3) downgrade and (4) finally import configurations applied to the attribute table of a layer. It is mainly based on the QgsAttributeTableConfig()
class and its methods.
Let's assume there is a point layer called 'points_in_polygon' with a corresponding attribute table, see the image below:
The first thing to start is to analyze all the configurations that the attribute table of the layer possesses.
<attributetableconfig sortOrder="0" sortExpression="" actionWidgetStyle="dropDown">
<columns>
<column hidden="0" type="field" width="-1" name="id"/>
<column hidden="0" type="field" width="-1" name="city"/>
<column hidden="0" type="field" width="-1" name="month"/>
<column hidden="0" type="field" width="-1" name="temp"/>
<column hidden="0" type="field" width="-1" name="avg"/>
<column hidden="0" type="field" width="-1" name="avg2"/>
<column hidden="1" type="actions" width="-1"/>
</columns>
</attributetableconfig>
For the attribute table itself via the QgsAttributeTableConfig
class:
method |
value |
explanation |
sortOrder() |
sortOrder="0" |
Gets the sort order. |
sortExpression() |
sortExpression="" |
Gets the expression used for sorting. |
actionWidgetStyle() |
actionWidgetStyle="dropDown" |
Gets the style of the action widget. |
For the fields/columns by means of the columns()
method, that launches the ColumnConfig
structure:
method |
value |
explanation |
hidden() |
hidden="0" |
Flag that controls if the column is hidden. |
name() |
name="id" |
The name of the attribute if this column represents a field. |
type() |
type="field" |
The type of this column. |
width() |
width="-1" |
Width of column, or -1 for default width. |
Now, the following things will be executed:
- apply some configurations to the layer's attribute table
- export those configurations to the XML file
- switch back to the default configurations
- import the configurations from the XML file
Step 1 : Adjusting the attribute table of the layer
There are several useful threads that can reinforce this procedure:
They can be easily combined into a single PyQGIS script to perform this task.
For the initial attribute table, it is supposed to:
- hide
"temp"
, "avg"
, and "avg2"
columns
- change the sort in descending order to the
"month"
field
- swap the order of fields to
"city"
, "month"
, and "id"
Now the attribute table will look like this:
Check how the QgsAttributeTableConfig
has changed:
<attributetableconfig actionWidgetStyle="dropDown" sortOrder="1" sortExpression=""month"">
<columns>
<column type="field" hidden="0" name="city" width="-1"/>
<column type="field" hidden="0" name="month" width="-1"/>
<column type="field" hidden="0" name="id" width="-1"/>
<column type="field" hidden="1" name="temp" width="-1"/>
<column type="field" hidden="1" name="avg" width="-1"/>
<column type="field" hidden="1" name="avg2" width="-1"/>
<column type="actions" hidden="1" width="-1"/>
</columns>
</attributetableconfig>
Step 2 : Exporting attribute table settings to the XML file
Export those styles to an XML file. Inspiration I found in this QGIS/tests/src/python/test_qgsvectorlayer_namedstyle.py
dir.
By means of the following code:
# imports
from qgis.core import QgsProject
from PyQt5.QtXml import QDomDocument
from os.path import realpath
# referring to a vector layer by its name
layer = QgsProject.instance().mapLayersByName("points_in_polygon")[0]
# getting the config of the layer's attribute table
config = layer.attributeTableConfig()
# creating QDomDocument and QDomNode holders for the config
settings = QDomDocument()
string_content = f"<!DOCTYPE {layer.name()}><settings></settings>"
settings.setContent(string_content)
node = settings.firstChild()
# writing attribute table config into an XML structure
config.writeXml(node)
# converting the QDomDocument to a string
settings_content = settings.toString()
# writting settings to an XML file
path_to_xml = realpath('D:/qgis_test/settings.xml')
with open(path_to_xml, 'w') as xml_file:
xml_file.write(settings_content)
Now there is an XML file 'settings.xml':
Step 3 : Switching back to the default attribute table settings
Now let's revert back to the default (empty) config of the layer's attribute table.
With this piece of code:
# imports
from qgis.core import QgsProject, QgsAttributeTableConfig
# referring to a vector layer by its name
layer = QgsProject.instance().mapLayersByName("points_in_polygon")[0]
# initiating a new config for the layer's attribute table
config = QgsAttributeTableConfig()
# downgrading to the default config of the layer's attribute table
layer.setAttributeTableConfig(config)
it is possible to get this:
Step 4 : Importing attribute table settings from the XML file
On the final step let's import styles from the 'settings.xml' XML file.
With this script:
# imports
from qgis.utils import iface
from qgis.core import QgsProject
from PyQt5.QtXml import QDomDocument
from os.path import realpath
from xml.dom import minidom
# referring to a vector layer by its name
layer = QgsProject.instance().mapLayersByName("points_in_polygon")[0]
# getting the config of the layer's attribute table
config = layer.attributeTableConfig()
# or initiating a new one also works
# config = QgsAttributeTableConfig()
# openning the XML file with settings
path_to_xml = realpath('D:/qgis_test/settings.xml')
xml_file = minidom.parse(path_to_xml)
# creating QDomDocument and QDomNode holders for the config
settings = QDomDocument()
settings.setContent(xml_file.toxml())
node = settings.firstChildElement('settings')
# reading attribute table config from an XML structure
config.readXml(node)
# applying a new setting for the layer's attribute table
layer.setAttributeTableConfig(config)
# showing the attribute table
iface.showAttributeTable(layer)
one can easily return to the custom config of the layer's attribute table:
References: