How can I make a particular column of my QTableView non-editable?
Asked Answered
M

6

13

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?

Melton answered 27/9, 2012 at 7:26 Comment(0)
D
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.

Drinkable answered 27/9, 2012 at 8:1 Comment(0)
P
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));
}
Petrochemistry answered 8/10, 2013 at 14:49 Comment(2)
Retrurning true instead of false in editorEvent will prevent createEditor from being called at all, as it consumes the event at that point.Amative
@Amative 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.Calliope
C
7

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

Cryan answered 9/9, 2015 at 20:43 Comment(2)
This method works for QTableWidges, but not for QTableViews, which is what the question is asking about.Rosetterosewall
Works on QTableView , Qt 4.8.4. Thanks.Overthrow
M
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.

Melton answered 27/9, 2012 at 11:42 Comment(1)
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.Bur
A
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;
}
Anapest answered 5/5, 2021 at 18:1 Comment(0)
I
0

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)
Insolent answered 2/3, 2013 at 2:39 Comment(2)
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!Conductivity
But how can this method be applied to a single column or row, as OP asks?Rhaetic

© 2022 - 2024 — McMap. All rights reserved.