12

I have a QTableView with 4 Rows and 4 columns each representing their data's in it. By default the QTableView is editable. Now I want to make any particular column as non editable in my QTableView.

How can I do it?

Thanks in Advance.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
New Moon
  • 787
  • 6
  • 21
  • 35

6 Answers6

13

You can use the setItemDelegateForColumn() function. Implement a read-only delegate, and set it for the column you need.

You can also use the flags inside your model, and remove the Qt::ItemIsEditable flag for a specific column.

Machta
  • 1,656
  • 2
  • 16
  • 28
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
12

Something like that may also do it:

class NotEditableDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit NotEditableDelegate(QObject *parent = 0)
        : QItemDelegate(parent)
    {}

protected:
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
    { return false; }
    QWidget* createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const
    { return Q_NULLPTR; }

};

In use:

// Make all the columns except the second read only
for(int c = 0; c < view->model()->columnCount(); c++)
{
    if(c != 1)
        view->setItemDelegateForColumn(c, new NotEditableDelegate(view));
}
phyatt
  • 18,472
  • 5
  • 61
  • 80
MasterAler
  • 1,614
  • 3
  • 23
  • 35
  • 1
    Retrurning true instead of false in editorEvent will prevent createEditor from being called at all, as it consumes the event at that point. – ricekab Nov 25 '19 at 09:48
  • @ricekab I'm not sure that is true: the doc says "The base implementation returns false (indicating that it has not handled the event)." and according to an experiment I just did returning false for a given `index.colum()` did not stop the editing. – mike rodent Sep 01 '21 at 18:08
6

The easiest way is settting the flag of the item you don't want to be editable in this way:

item->setFlags(item->flags() &  ~Qt::ItemIsEditable);

You can also check this thread: Qt How to make a column in QTableWidget read only

Community
  • 1
  • 1
Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
1

In the overide method just change it to if(!(index.column() == 0) and change the Flag value as Flag |= Qt::ItemisEditable.
This Works Fine.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
New Moon
  • 787
  • 6
  • 21
  • 35
  • I guess you meant overriding `bool QAbstractItemView::edit(const QModelIndex & index, EditTrigger trigger, QEvent * event)` didn't you? In such case you can just return `false` for read-only column. – Michał Walenciak Nov 18 '14 at 19:33
1

May be this late, but for future reference. You should set the table view to NoEditTrigger like this:

myTableView->setModel(model);
myTableView->setEditTriggers(QAbstractItemView::NoEditTriggers)
SIFE
  • 5,567
  • 7
  • 32
  • 46
  • 1
    Wow, that's the cleanest solution I've seen up to now, especially if you only want the data to be read-only in _one_ of your views on the same model. Thanks! – Charl Botha May 29 '13 at 13:05
  • 16
    But how can this method be applied to a single column or row, as OP asks? – Matt Phillips Jun 12 '14 at 12:10
1

You need to override the 'flags' method and specify the editability parameters of the element for the selected column

Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return Qt::NoItemFlags;
    if(index.column() == SELECTED_COLUMN_NUM)
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}