QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsattributeactiondialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsattributeactiondialog.cpp - attribute action dialog
3 -------------------
4
5This class creates and manages the Action tab of the Vector Layer
6Properties dialog box. Changes made in the dialog box are propagated
7back to QgsVectorLayer.
8
9 begin : October 2004
10 copyright : (C) 2004 by Gavin Macaulay
11 email : gavin at macaulay dot co dot nz
12 ***************************************************************************/
13
14/***************************************************************************
15 * *
16 * This program is free software; you can redistribute it and/or modify *
17 * it under the terms of the GNU General Public License as published by *
18 * the Free Software Foundation; either version 2 of the License, or *
19 * (at your option) any later version. *
20 * *
21 ***************************************************************************/
22
24
25#include "qgsaction.h"
26#include "qgsactionmanager.h"
28#include "qgsvectorlayer.h"
29
30#include <QFileDialog>
31#include <QHeaderView>
32#include <QImageWriter>
33#include <QMessageBox>
34#include <QSettings>
35#include <QString>
36#include <QTableWidget>
37
38#include "moc_qgsattributeactiondialog.cpp"
39
40using namespace Qt::StringLiterals;
41
43 : QWidget( parent )
44 , mLayer( actions.layer() )
45{
46 setupUi( this );
47 QHeaderView *header = mAttributeActionTable->horizontalHeader();
48 header->setHighlightSections( false );
49 header->setStretchLastSection( true );
50 mAttributeActionTable->setColumnWidth( 0, 100 );
51 mAttributeActionTable->setColumnWidth( 1, 230 );
52 mAttributeActionTable->setCornerButtonEnabled( false );
53 mAttributeActionTable->setEditTriggers( QAbstractItemView::AnyKeyPressed | QAbstractItemView::SelectedClicked );
54
55 connect( mAttributeActionTable, &QTableWidget::itemDoubleClicked, this, &QgsAttributeActionDialog::itemDoubleClicked );
56 connect( mAttributeActionTable, &QTableWidget::itemSelectionChanged, this, &QgsAttributeActionDialog::updateButtons );
57 connect( mMoveUpButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::moveUp );
58 connect( mMoveDownButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::moveDown );
59 connect( mRemoveButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::remove );
60 connect( mAddButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::insert );
61 connect( mDuplicateButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::duplicate );
62 connect( mAddDefaultActionsButton, &QAbstractButton::clicked, this, &QgsAttributeActionDialog::addDefaultActions );
63
64 init( actions, mLayer->attributeTableConfig() );
65}
66
68{
69 // Start from a fresh slate.
70 mAttributeActionTable->setRowCount( 0 );
71
72 int i = 0;
73 // Populate with our actions.
74 const auto constActions = actions.actions();
75 for ( const QgsAction &action : constActions )
76 {
77 insertRow( i++, action );
78 }
79
80 updateButtons();
81
83 visibleActionWidgetConfig.type = QgsAttributeTableConfig::Action;
84 visibleActionWidgetConfig.hidden = false;
85
86 mShowInAttributeTable->setChecked( attributeTableConfig.actionWidgetVisible() );
87 mAttributeTableWidgetType->setCurrentIndex( attributeTableConfig.actionWidgetStyle() );
88}
89
90QList<QgsAction> QgsAttributeActionDialog::actions() const
91{
92 QList<QgsAction> actions;
93
94 for ( int i = 0; i < mAttributeActionTable->rowCount(); ++i )
95 {
96 actions.append( rowToAction( i ) );
97 }
98
99 return actions;
100}
101
103{
104 return mShowInAttributeTable->isChecked();
105}
106
111
112void QgsAttributeActionDialog::insertRow( int row, const QgsAction &action )
113{
114 QTableWidgetItem *item = nullptr;
115 mAttributeActionTable->insertRow( row );
116
117 // Type
118 item = new QTableWidgetItem( textForType( action.type() ) );
119 item->setData( Role::ActionType, static_cast<int>( action.type() ) );
120 item->setData( Role::ActionId, action.id() );
121 item->setFlags( item->flags() & ~Qt::ItemIsEditable );
122 mAttributeActionTable->setItem( row, Type, item );
123
124 // Description
125 mAttributeActionTable->setItem( row, Description, new QTableWidgetItem( action.name() ) );
126
127 // Short Title
128 mAttributeActionTable->setItem( row, ShortTitle, new QTableWidgetItem( action.shortTitle() ) );
129
130 // Action text
131 item = new QTableWidgetItem( action.command().length() > 30 ? action.command().left( 27 ) + "…" : action.command() );
132 item->setData( Qt::UserRole, action.command() );
133 mAttributeActionTable->setItem( row, ActionText, item );
134
135 // Capture output
136 item = new QTableWidgetItem();
137 item->setFlags( item->flags() & ~( Qt::ItemIsEditable ) );
138 item->setCheckState( action.capture() ? Qt::Checked : Qt::Unchecked );
139 mAttributeActionTable->setItem( row, Capture, item );
140
141 // Scopes
142 item = new QTableWidgetItem();
143 item->setFlags( item->flags() & ~( Qt::ItemIsEditable ) );
144 QStringList actionScopes = qgis::setToList( action.actionScopes() );
145 std::sort( actionScopes.begin(), actionScopes.end() );
146 item->setText( actionScopes.join( ", "_L1 ) );
147 item->setData( Qt::UserRole, QVariant::fromValue<QSet<QString>>( action.actionScopes() ) );
148 mAttributeActionTable->setItem( row, ActionScopes, item );
149
150 // Icon
151 const QIcon icon = action.icon();
152 QTableWidgetItem *headerItem = new QTableWidgetItem( icon, QString() );
153 headerItem->setData( Qt::UserRole, action.iconPath() );
154 mAttributeActionTable->setVerticalHeaderItem( row, headerItem );
155
156 // Notification message
157 mAttributeActionTable->setItem( row, NotificationMessage, new QTableWidgetItem( action.notificationMessage() ) );
158
159 // EnabledOnlyWhenEditable
160 item = new QTableWidgetItem();
161 item->setFlags( item->flags() & ~( Qt::ItemIsEditable ) );
162 item->setCheckState( action.isEnabledOnlyWhenEditable() ? Qt::Checked : Qt::Unchecked );
163 mAttributeActionTable->setItem( row, EnabledOnlyWhenEditable, item );
164
165 updateButtons();
166}
167
168void QgsAttributeActionDialog::insertRow( int row, Qgis::AttributeActionType type, const QString &name, const QString &actionText, const QString &iconPath, bool capture, const QString &shortTitle, const QSet<QString> &actionScopes, const QString &notificationMessage, bool isEnabledOnlyWhenEditable )
169{
170 if ( uniqueName( name ) == name )
171 insertRow( row, QgsAction( type, name, actionText, iconPath, capture, shortTitle, actionScopes, notificationMessage, isEnabledOnlyWhenEditable ) );
172}
173
174void QgsAttributeActionDialog::moveUp()
175{
176 // Swap the selected row with the one above
177
178 int row1 = -1, row2 = -1;
179 QList<QTableWidgetItem *> selection = mAttributeActionTable->selectedItems();
180 if ( !selection.isEmpty() )
181 {
182 row1 = selection.first()->row();
183 }
184
185 if ( row1 > 0 )
186 row2 = row1 - 1;
187
188 if ( row1 != -1 && row2 != -1 )
189 {
190 swapRows( row1, row2 );
191 // Move the selection to follow
192 mAttributeActionTable->selectRow( row2 );
193 }
194}
195
196void QgsAttributeActionDialog::moveDown()
197{
198 // Swap the selected row with the one below
199 int row1 = -1, row2 = -1;
200 QList<QTableWidgetItem *> selection = mAttributeActionTable->selectedItems();
201 if ( !selection.isEmpty() )
202 {
203 row1 = selection.first()->row();
204 }
205
206 if ( row1 < mAttributeActionTable->rowCount() - 1 )
207 row2 = row1 + 1;
208
209 if ( row1 != -1 && row2 != -1 )
210 {
211 swapRows( row1, row2 );
212 // Move the selection to follow
213 mAttributeActionTable->selectRow( row2 );
214 }
215}
216
217void QgsAttributeActionDialog::swapRows( int row1, int row2 )
218{
219 const int colCount = mAttributeActionTable->columnCount();
220 for ( int col = 0; col < colCount; col++ )
221 {
222 QTableWidgetItem *item = mAttributeActionTable->takeItem( row1, col );
223 mAttributeActionTable->setItem( row1, col, mAttributeActionTable->takeItem( row2, col ) );
224 mAttributeActionTable->setItem( row2, col, item );
225 }
226 QTableWidgetItem *header = mAttributeActionTable->takeVerticalHeaderItem( row1 );
227 mAttributeActionTable->setVerticalHeaderItem( row1, mAttributeActionTable->takeVerticalHeaderItem( row2 ) );
228 mAttributeActionTable->setVerticalHeaderItem( row2, header );
229}
230
231QgsAction QgsAttributeActionDialog::rowToAction( int row ) const
232{
233 const QUuid id { mAttributeActionTable->item( row, Type )->data( Role::ActionId ).toUuid() };
234 QgsAction action( id, static_cast<Qgis::AttributeActionType>( mAttributeActionTable->item( row, Type )->data( Role::ActionType ).toInt() ), mAttributeActionTable->item( row, Description )->text(), mAttributeActionTable->item( row, ActionText )->data( Qt::UserRole ).toString(), mAttributeActionTable->verticalHeaderItem( row )->data( Qt::UserRole ).toString(), mAttributeActionTable->item( row, Capture )->checkState() == Qt::Checked, mAttributeActionTable->item( row, ShortTitle )->text(), mAttributeActionTable->item( row, ActionScopes )->data( Qt::UserRole ).value<QSet<QString>>(), mAttributeActionTable->item( row, NotificationMessage )->text(), mAttributeActionTable->item( row, EnabledOnlyWhenEditable )->checkState() == Qt::Checked );
235 return action;
236}
237
238QString QgsAttributeActionDialog::textForType( Qgis::AttributeActionType type )
239{
240 switch ( type )
241 {
243 return tr( "Generic" );
245 return tr( "Python" );
247 return tr( "macOS" );
249 return tr( "Windows" );
251 return tr( "Unix" );
253 return tr( "Open URL" );
255 return tr( "Submit URL (urlencoded or JSON)" );
257 return tr( "Submit URL (multipart)" );
258 }
259 return QString();
260}
261
262void QgsAttributeActionDialog::remove()
263{
264 QList<QTableWidgetItem *> selection = mAttributeActionTable->selectedItems();
265 if ( !selection.isEmpty() )
266 {
267 // Remove the selected row.
268 int row = selection.first()->row();
269 mAttributeActionTable->removeRow( row );
270
271 // And select the row below the one that was selected or the last one.
272 if ( row >= mAttributeActionTable->rowCount() )
273 row = mAttributeActionTable->rowCount() - 1;
274 mAttributeActionTable->selectRow( row );
275
276 updateButtons();
277 }
278}
279
280void QgsAttributeActionDialog::insert()
281{
282 // Add the action details as a new row in the table.
283 const int pos = mAttributeActionTable->rowCount();
284
285 QgsAttributeActionPropertiesDialog dlg( mLayer, this );
286 dlg.setWindowTitle( tr( "Add New Action" ) );
287
288 if ( dlg.exec() )
289 {
290 const QString name = uniqueName( dlg.description() );
291
292 insertRow( pos, dlg.type(), name, dlg.actionText(), dlg.iconPath(), dlg.capture(), dlg.shortTitle(), dlg.actionScopes(), dlg.notificationMessage(), dlg.isEnabledOnlyWhenEditable() );
293 }
294}
295
296void QgsAttributeActionDialog::duplicate()
297{
298 // Add the action details as a new row in the table.
299 const int pos = mAttributeActionTable->rowCount();
300 const int row = mAttributeActionTable->currentRow();
301
302 QgsAttributeActionPropertiesDialog dlg(
303 static_cast<Qgis::AttributeActionType>( mAttributeActionTable->item( row, Type )->data( Role::ActionType ).toInt() ),
304 mAttributeActionTable->item( row, Description )->text(),
305 mAttributeActionTable->item( row, ShortTitle )->text(),
306 mAttributeActionTable->verticalHeaderItem( row )->data( Qt::UserRole ).toString(),
307 mAttributeActionTable->item( row, ActionText )->data( Qt::UserRole ).toString(),
308 mAttributeActionTable->item( row, Capture )->checkState() == Qt::Checked,
309 mAttributeActionTable->item( row, ActionScopes )->data( Qt::UserRole ).value<QSet<QString>>(),
310 mAttributeActionTable->item( row, NotificationMessage )->text(),
311 mAttributeActionTable->item( row, EnabledOnlyWhenEditable )->checkState() == Qt::Checked,
312 mLayer
313 );
314
315 dlg.setWindowTitle( tr( "Duplicate Action" ) );
316
317 if ( dlg.exec() )
318 {
319 const QString name = uniqueName( dlg.description() );
320
321 insertRow( pos, dlg.type(), name, dlg.actionText(), dlg.iconPath(), dlg.capture(), dlg.shortTitle(), dlg.actionScopes(), dlg.notificationMessage(), dlg.isEnabledOnlyWhenEditable() );
322 }
323}
324
325void QgsAttributeActionDialog::updateButtons()
326{
327 QList<QTableWidgetItem *> selection = mAttributeActionTable->selectedItems();
328 const bool hasSelection = !selection.isEmpty();
329
330 if ( hasSelection )
331 {
332 const int row = selection.first()->row();
333 mMoveUpButton->setEnabled( row >= 1 );
334 mMoveDownButton->setEnabled( row >= 0 && row < mAttributeActionTable->rowCount() - 1 );
335 }
336 else
337 {
338 mMoveUpButton->setEnabled( false );
339 mMoveDownButton->setEnabled( false );
340 }
341
342 mRemoveButton->setEnabled( hasSelection );
343 mDuplicateButton->setEnabled( hasSelection );
344}
345
346void QgsAttributeActionDialog::addDefaultActions()
347{
348 int pos = 0;
349 insertRow( pos++, Qgis::AttributeActionType::Generic, tr( "Echo attribute's value" ), u"echo \"[% @field_value %]\""_s, QString(), true, tr( "Attribute Value" ), QSet<QString>() << u"Field"_s, QString() );
350 insertRow( pos++, Qgis::AttributeActionType::Generic, tr( "Run an application" ), u"ogr2ogr -f \"GPKG\" \"[% \"OUTPUT_PATH\" %]\" \"[% \"INPUT_FILE\" %]\""_s, QString(), true, tr( "Run application" ), QSet<QString>() << u"Feature"_s << u"Canvas"_s, QString() );
351 insertRow( pos++, Qgis::AttributeActionType::GenericPython, tr( "Display the feature id in the message bar" ), u"from qgis.utils import iface\n\niface.messageBar().pushInfo(\"Feature id\", \"The feature id is [% $id %]\")"_s, QString(), false, tr( "Feature ID" ), QSet<QString>() << u"Feature"_s << u"Canvas"_s, QString() );
352 insertRow( pos++, Qgis::AttributeActionType::GenericPython, tr( "Selected field's value (Identify features tool)" ), u"from qgis.PyQt import QtWidgets\n\nQtWidgets.QMessageBox.information(None, \"Current field's value\", \"[% @field_name %] = [% @field_value %]\")"_s, QString(), false, tr( "Field Value" ), QSet<QString>() << u"Field"_s, QString() );
353 insertRow( pos++, Qgis::AttributeActionType::GenericPython, tr( "Clicked coordinates (Run feature actions tool)" ), u"from qgis.PyQt import QtWidgets\n\nQtWidgets.QMessageBox.information(None, \"Clicked coords\", \"layer: [% @layer_id %]\\ncoords: ([% @click_x %],[% @click_y %])\")"_s, QString(), false, tr( "Clicked Coordinate" ), QSet<QString>() << u"Canvas"_s, QString() );
354 insertRow( pos++, Qgis::AttributeActionType::OpenUrl, tr( "Open file" ), u"[% \"PATH\" %]"_s, QString(), false, tr( "Open file" ), QSet<QString>() << u"Feature"_s << u"Canvas"_s, QString() );
355 insertRow( pos++, Qgis::AttributeActionType::OpenUrl, tr( "Search on web based on attribute's value" ), u"https://www.google.com/search?q=[% @field_value %]"_s, QString(), false, tr( "Search Web" ), QSet<QString>() << u"Field"_s, QString() );
356 insertRow( pos++, Qgis::AttributeActionType::GenericPython, tr( "List feature ids" ), u"from qgis.PyQt import QtWidgets\n\nlayer = QgsProject.instance().mapLayer('[% @layer_id %]')\nif layer.selectedFeatureCount():\n ids = layer.selectedFeatureIds()\nelse:\n ids = [f.id() for f in layer.getFeatures()]\n\nQtWidgets.QMessageBox.information(None, \"Feature ids\", ', '.join([str(id) for id in ids]))"_s, QString(), false, tr( "List feature ids" ), QSet<QString>() << u"Layer"_s, QString() );
357 insertRow( pos++, Qgis::AttributeActionType::GenericPython, tr( "Duplicate selected features" ), u"project = QgsProject.instance()\nlayer = QgsProject.instance().mapLayer('[% @layer_id %]')\nif not layer.isEditable():\n qgis.utils.iface.messageBar().pushMessage( 'Cannot duplicate feature in not editable mode on layer {layer}'.format( layer=layer.name() ) )\nelse:\n features=[]\n if len('[% $id %]')>0:\n features.append( layer.getFeature( [% $id %] ) )\n else:\n for x in layer.selectedFeatures():\n features.append( x )\n feature_count=0\n children_info=''\n featureids=[]\n for f in features:\n result=QgsVectorLayerUtils.duplicateFeature(layer, f, project, 0 )\n featureids.append( result[0].id() )\n feature_count+=1\n for ch_layer in result[1].layers():\n children_info+='{number_of_children} children on layer {children_layer}\\n'.format( number_of_children=str( len( result[1].duplicatedFeatures(ch_layer) ) ), children_layer=ch_layer.name() )\n ch_layer.selectByIds( result[1].duplicatedFeatures(ch_layer) )\n layer.selectByIds( featureids )\n qgis.utils.iface.messageBar().pushMessage( '{number_of_features} features on layer {layer} duplicated with\\n{children_info}'.format( number_of_features=str( feature_count ), layer=layer.name(), children_info=children_info ) )"_s, QString(), false, tr( "Duplicate selected" ), QSet<QString>() << u"Layer"_s, QString(), true );
358}
359
360void QgsAttributeActionDialog::itemDoubleClicked( QTableWidgetItem *item )
361{
362 const int row = item->row();
363
364 QgsAttributeActionPropertiesDialog actionProperties(
365 static_cast<Qgis::AttributeActionType>( mAttributeActionTable->item( row, Type )->data( Role::ActionType ).toInt() ),
366 mAttributeActionTable->item( row, Description )->text(),
367 mAttributeActionTable->item( row, ShortTitle )->text(),
368 mAttributeActionTable->verticalHeaderItem( row )->data( Qt::UserRole ).toString(),
369 mAttributeActionTable->item( row, ActionText )->data( Qt::UserRole ).toString(),
370 mAttributeActionTable->item( row, Capture )->checkState() == Qt::Checked,
371 mAttributeActionTable->item( row, ActionScopes )->data( Qt::UserRole ).value<QSet<QString>>(),
372 mAttributeActionTable->item( row, NotificationMessage )->text(),
373 mAttributeActionTable->item( row, EnabledOnlyWhenEditable )->checkState() == Qt::Checked,
374 mLayer
375 );
376
377 actionProperties.setWindowTitle( tr( "Edit Action" ) );
378
379 if ( actionProperties.exec() )
380 {
381 mAttributeActionTable->item( row, Type )->setData( Role::ActionType, static_cast<int>( actionProperties.type() ) );
382 mAttributeActionTable->item( row, Type )->setText( textForType( actionProperties.type() ) );
383 mAttributeActionTable->item( row, Description )->setText( actionProperties.description() );
384 mAttributeActionTable->item( row, ShortTitle )->setText( actionProperties.shortTitle() );
385 mAttributeActionTable->item( row, ActionText )->setText( actionProperties.actionText().length() > 30 ? actionProperties.actionText().left( 27 ) + "…" : actionProperties.actionText() );
386 mAttributeActionTable->item( row, ActionText )->setData( Qt::UserRole, actionProperties.actionText() );
387 mAttributeActionTable->item( row, Capture )->setCheckState( actionProperties.capture() ? Qt::Checked : Qt::Unchecked );
388 mAttributeActionTable->item( row, NotificationMessage )->setText( actionProperties.notificationMessage() );
389 mAttributeActionTable->item( row, EnabledOnlyWhenEditable )->setCheckState( actionProperties.isEnabledOnlyWhenEditable() ? Qt::Checked : Qt::Unchecked );
390
391 QTableWidgetItem *item = mAttributeActionTable->item( row, ActionScopes );
392 QStringList actionScopes = qgis::setToList( actionProperties.actionScopes() );
393 std::sort( actionScopes.begin(), actionScopes.end() );
394 item->setText( actionScopes.join( ", "_L1 ) );
395 item->setData( Qt::UserRole, QVariant::fromValue<QSet<QString>>( actionProperties.actionScopes() ) );
396
397 mAttributeActionTable->verticalHeaderItem( row )->setData( Qt::UserRole, actionProperties.iconPath() );
398 mAttributeActionTable->verticalHeaderItem( row )->setIcon( QIcon( actionProperties.iconPath() ) );
399 }
400}
401
402QString QgsAttributeActionDialog::uniqueName( QString name )
403{
404 // Make sure that the given name is unique, adding a numerical
405 // suffix if necessary.
406
407 const int pos = mAttributeActionTable->rowCount();
408 bool unique = true;
409
410 for ( int i = 0; i < pos; ++i )
411 {
412 if ( mAttributeActionTable->item( i, Description )->text() == name )
413 unique = false;
414 }
415
416 if ( !unique )
417 {
418 int suffix_num = 1;
419 QString new_name;
420 while ( !unique )
421 {
422 const QString suffix = QString::number( suffix_num );
423 new_name = name + '_' + suffix;
424 unique = true;
425 for ( int i = 0; i < pos; ++i )
426 if ( mAttributeActionTable->item( i, 0 )->text() == new_name )
427 unique = false;
428 ++suffix_num;
429 }
430 name = new_name;
431 }
432 return name;
433}
AttributeActionType
Attribute action types.
Definition qgis.h:4747
@ Mac
MacOS specific.
Definition qgis.h:4750
@ OpenUrl
Open URL action.
Definition qgis.h:4753
@ Unix
Unix specific.
Definition qgis.h:4752
@ SubmitUrlMultipart
POST data to an URL using "multipart/form-data".
Definition qgis.h:4755
@ Windows
Windows specific.
Definition qgis.h:4751
@ SubmitUrlEncoded
POST data to an URL, using "application/x-www-form-urlencoded" or "application/json" if the body is v...
Definition qgis.h:4754
Storage and management of actions associated with a layer.
Utility class that encapsulates an action based on vector attributes.
Definition qgsaction.h:38
QString notificationMessage() const
Returns the notification message that triggers the action.
Definition qgsaction.h:151
QString name() const
The name of the action. This may be a longer description.
Definition qgsaction.h:116
QSet< QString > actionScopes() const
The action scopes define where an action will be available.
Qgis::AttributeActionType type() const
The action type.
Definition qgsaction.h:154
QIcon icon() const
The icon.
Definition qgsaction.h:137
QString iconPath() const
The path to the icon.
Definition qgsaction.h:134
QString command() const
Returns the command that is executed by this action.
Definition qgsaction.h:145
QString shortTitle() const
The short title is used to label user interface elements like buttons.
Definition qgsaction.h:119
bool isEnabledOnlyWhenEditable() const
Returns whether only enabled in editable mode.
Definition qgsaction.h:161
bool capture() const
Whether to capture output for display when this action is run.
Definition qgsaction.h:157
QUuid id() const
Returns a unique id for this action.
Definition qgsaction.h:125
void init(const QgsActionManager &action, const QgsAttributeTableConfig &attributeTableConfig)
QgsAttributeActionDialog(const QgsActionManager &actions, QWidget *parent=nullptr)
QList< QgsAction > actions() const
QgsAttributeTableConfig::ActionWidgetStyle attributeTableWidgetStyle() const
A container for configuration of the attribute table.
@ Action
This column represents an action widget.
ActionWidgetStyle
The style of the action widget in the attribute table.
bool actionWidgetVisible() const
Returns true if the action widget is visible.
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
Defines the configuration of a column in the attribute table.
QgsAttributeTableConfig::Type type
The type of this column.
bool hidden
Flag that controls if the column is hidden.