3

I want to dock at the right the attribute table of layer "Constantes" in QGIS 3.30. I found resources and tried this code :

layer_name = "Constantes"
layers = QgsProject.instance().mapLayersByName(layer_name)
 
if len(layers) == 1:
 layer = layers[0] 
 attr_table = iface.showAttributeTable(layer) 
 widgets = QApplication.instance().allWidgets()
 attrTables = [t for t in widgets if t.objectName() == u'AttributeTable']
 for table in attrTables:
 iface.addDockWidget(Qt.LeftDockWidgetArea, table)

The attribute table displays in a new window but not docked. attrTables is empty that's why it does not work.

Is there a way to correct the code ?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Jan 3 at 13:08

2 Answers 2

3

Soon before your answer, I find other way (maybe not very clean but it worked) :

QSettings().setValue("/Qgis/dockAttributeTable", True)
layer_name = "Constantes"
layers = QgsProject.instance().mapLayersByName(layer_name)
if len(layers) == 1: 
 layer = layers[0] 
 iface.showAttributeTable(layer) 
 
 for dock in iface.mainWindow().findChildren(QDockWidget): 
 if layer_name in dock.windowTitle():
 iface.addDockWidget(Qt.LeftDockWidgetArea, dock)
 
Vince
20.5k16 gold badges49 silver badges65 bronze badges
answered Jan 3 at 18:25
1
  • I'm glad you were able to solve it. I would argue that it is indeed a cleaner version of my second method. It's nice to learn of the dockAttributeTable setting. Commented Jan 3 at 20:43
2

You can get a reference to the open attribute table's container by using attr_table.parent(). However, the problem you will consequently face is that the container is not a QgsDockWidget (it is a QDialog) and you will not be able to dock it. This can be demonstrated by attempting to dock the attribute table manually by dragging it over a dockable area.

What you can do is create a new QgsDockWidget and place the attribute table inside it. This can then be docked in the way you attempted.

layer_name = 'Constantes'
layers = QgsProject.instance().mapLayersByName(layer_name)
 
if len(layers) == 1:
 layer = layers[0] 
 attr_table = iface.showAttributeTable(layer)
 
# create a new QgsDockWidget and set its title to be the layer name
dock_widget = QgsDockWidget(layer.name())
# assign the attribute table to the dockwidget (via its parent)
dock_widget.setWidget(attr_table.parent())
# dock the widget
iface.addDockWidget(Qt.LeftDockWidgetArea, dock_widget)

Note: this method will cause undesirable behaviour if the Dock attribute table action in the attribute table is clicked after docking it this way (a new QgsDockWidget will be created and the attribute table will move into it, leaving the empty dockwidget still visible in the Qt.LeftDockWidgetArea).

Alternative method

This method first docks the attribute table by programmatically clicking the Dock Attribute Table action and then shifting the automatically generated QgsDockWidget to the desired area.

The advantage is that the the action button is then toggled on when the attribute table is docked. Clicking the action button will undock the attribute table as intended.

layer_name = 'Constantes'
layers = QgsProject.instance().mapLayersByName(layer_name)
 
if len(layers) == 1:
 layer = layers[0] 
 attr_table = iface.showAttributeTable(layer)
 widgets = QApplication.instance().allWidgets()
 
# get a list of children of the attribute table
# this includes the action buttons
attribute_table_children = attr_table.children()
# get a reference to the 'Dock Attribute Table' action
dock_action = [child for child in attribute_table_children if hasattr(child, 'toolTip') and child.toolTip() == 'Dock Attribute Table'][0]
# trigger the 'Dock Attribute Table' action
dock_action.trigger()
# get a reference to the parent of the attribute table which is now a QgsDockWidget
dock_widget = attr_table.parent()
# dock the attribute table
iface.addDockWidget(Qt.LeftDockWidgetArea, dock_widget)
answered Jan 3 at 15:34
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.