6

Can I change the width of the drop-down field (attribute) list in the attribute table that is used for editing, i.e. the highlighted drop-down in the image below with the value "ID"? The list is so narrow I can't see field names easily. enter image description here

Oisin
  • 1,826
  • 9
  • 20
  • Unfortunately that didn't help. – Oisin Nov 28 '23 at 09:58
  • 1
    I have tried this again today and yours (Taras) and Louis's solutions now both work. I think there must have been some sort of corruption in my project file - before trying today I had recreated the project. Mnay thanks for your help. – Oisin Nov 29 '23 at 10:54

2 Answers2

6

There is a PyQGIS solution I can suggest. Honestly, it was tricky, and not straightforward.

The thing you are looking for is the QFrame hidden under AttributeTable / mUpdateExpressionBox / mFieldCombo. It has a corresponding method for that called setFixedWidth().

Let's assume there is a point layer with an opened attribute table in edited mode, see the below:

input

The default width of this drop-down list is 100, possible to see by means of the width() method.

Proceed with Plugins > Python Console > Show Editor and paste the script below:

# imports
from qgis.utils import iface
from qgis.core import QgsProject
from PyQt5.QtWidgets import QApplication, QFrame

accessing layer by its name

layer = QgsProject.instance().mapLayersByName("points_in_polygon")[0]

looking for the attribute table widget

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

if layer has no opened attribute table, open it

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() and layer.name() in widget.objectName()]

finding attribute table widget that matches layer name

for widget in attribute_table_widgets: # looping over elements of the layer's attribute table for elem1 in widget.children(): if elem1.objectName() == 'mUpdateExpressionBox': for elem2 in elem1.children(): if elem2.objectName() == 'mFieldCombo': for elem3 in elem2.children(): if isinstance(elem3, QFrame): # here change to desired width value elem3.setFixedWidth(500)

Change the name of your input layer. Press Run script run script and get the output that will look like this:

result

Now the new width is 500.

This solution will work as long as you keep your attribute table open, does not matter if it will be edited multiple times.

Perhaps, there is more easier way to exist.

P.S. I would appreciate it if someone could try this code.


References:

Kalak
  • 3,848
  • 8
  • 26
Taras
  • 32,823
  • 4
  • 66
  • 137
4

To complement @Taras's answer with a simpler python code (changed with edit):

# imports
from qgis.utils import iface
from qgis.core import QgsProject
from PyQt5.QtWidgets import QApplication, QFrame

accessing layer by its name

layer = QgsProject.instance().mapLayersByName("points_in_polygon")[0]

looking for the attribute table widget

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

if layer has no opened attribute table, open it

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() and layer.id() in widget.objectName() ]

finding attribute table widget that matches layer name

for widget in attribute_table_widgets: # get the right combo box of the layer's attribute table update_expression_box = widget.findChild(QFrame, "mUpdateExpressionBox") combo_box = update_expression_box.findChild(QComboBox, "mFieldCombo")

# change the width of the entire combo box
combo_box.setFixedWidth(500)

# or to only change the width of the drop-down list (same as @Taras)
# drop_down_list = combo_box.findChild(QFrame, "")
# drop_down_list.setFixedWidth(500)

EDIT:

The name of the layer cannot contain "-" (or be different than the source name of the layer) otherwise the condition layer.name() in widget.objectName() will fail.

Because it check that the layer name is in the object name of the QgsAttributeTableDialog object which is built like so: "QgsAttributeTableDialog/@layer_id". The problem being that "-" cannot exist in the @layer_id. Meaning that "-" in the layer name are converted to "_" in the layer id.

The solution being that using layer.id() will work more reliably than layer.name()

Kalak
  • 3,848
  • 8
  • 26