Discussion:
[Interest] How to make a column of a QTableView read-only?
K. Frank
2012-07-01 18:50:49 UTC
Permalink
Hello List!

I have a QTableView (backed by a QSqlTableModel) and am looking
for a simple way to make a column read-only. Poking around in the
documentation, I don't see anything obviously simple.

I see two approaches:

Attach a delegate to the column that provides a null or no-op editor.

Drill down somehow to get the individual items, and set the ItemIsEditable
flag of their ItemFlags to false.

I've seen what appear to be these two methods suggested on various
Qt forums, but they both seem to a little bit roundabout for something
that is both simple and generally useful. (I've also seen hints that a
simple method was available in Qt 3.)

Is there something simple and straightforward that I am overlooking
(like QTableView::setColumnReadonly (int columnIndex))?

Thanks for any pointers.


K. Frank
Sean Harmer
2012-07-01 19:11:53 UTC
Permalink
Hi K. Frank,
Post by K. Frank
Hello List!
I have a QTableView (backed by a QSqlTableModel) and am looking
for a simple way to make a column read-only. Poking around in the
documentation, I don't see anything obviously simple.
Take a look at the function QAbstractItemModel::flags(). You can
override this in your model such that flags it returns do not include
Qt::ItemIsEditable for the column you wish to be read-only.

Sean
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
K. Frank
2012-07-01 19:50:54 UTC
Permalink
Hi Sean!

Thank you for the suggestion.
Post by Sean Harmer
Hi K. Frank,
Post by K. Frank
Hello List!
I have a QTableView (backed by a QSqlTableModel) and am looking
for a simple way to make a column read-only. Poking around in the
documentation, I don't see anything obviously simple.
Take a look at the function QAbstractItemModel::flags(). You can
override this in your model such that flags it returns do not include
Qt::ItemIsEditable for the column you wish to be read-only.
To make sure I understand:

In my concrete case, I would then derive from QSqlTableModel,
override its flags() member function, and add to the derived class
some kind of setColumnReadonly() member function (or add some
kind of readonlyColumnIndex to its constructor) to tell flags() which
columns to flag as read-only. Is that the idea?

Also, do i take it correctly from your answer that there isn't another
way that is clearly simpler?

For me, this approach is fine. But, as an aside, read-only can be
either a model attribute (if the model is read-only or const) or a view
attribute (if you have a read-only view into a non-read-only model).

In my case, I have only one view into the model, so I can use your
suggested approach to make (a column of) the model read-only.
But, for future reference, what's the best way to make the view
read-only? (For example, what if my application has two views
into the same model, only one of which should be read-only?)
Post by Sean Harmer
Sean
Thanks for any additional thoughts.


K. Frank
André Somers
2012-07-02 07:42:40 UTC
Permalink
Post by K. Frank
Hi Sean!
Thank you for the suggestion.
Post by Sean Harmer
Hi K. Frank,
Post by K. Frank
Hello List!
I have a QTableView (backed by a QSqlTableModel) and am looking
for a simple way to make a column read-only. Poking around in the
documentation, I don't see anything obviously simple.
Take a look at the function QAbstractItemModel::flags(). You can
override this in your model such that flags it returns do not include
Qt::ItemIsEditable for the column you wish to be read-only.
In my concrete case, I would then derive from QSqlTableModel,
override its flags() member function, and add to the derived class
some kind of setColumnReadonly() member function (or add some
kind of readonlyColumnIndex to its constructor) to tell flags() which
columns to flag as read-only. Is that the idea?
Also, do i take it correctly from your answer that there isn't another
way that is clearly simpler?
For me, this approach is fine. But, as an aside, read-only can be
either a model attribute (if the model is read-only or const) or a view
attribute (if you have a read-only view into a non-read-only model).
In my case, I have only one view into the model, so I can use your
suggested approach to make (a column of) the model read-only.
But, for future reference, what's the best way to make the view
read-only? (For example, what if my application has two views
into the same model, only one of which should be read-only?)
You can use a proxy model to do that. There is a ready-made one that
does what you want available on the qt-project wiki:
http://qt-project.org/wiki/QSortFilterProxyModel_subclass_for_readonly_columns_columns_with_checkboxes_and_password_columns

If you have multiple views on a single model with different demands for
what column should be read-only, you can create multiple proxy models on
the same SQL model.

One note on the wiki article: for Qt 4.8 and up, you should replace the
use of QSortFilterProxyModel with QIdentityProxyModel (as long as you
don't need filtering or sorting too, that is).

André
K. Frank
2012-07-02 14:18:45 UTC
Permalink
Hello André!

Thank you for the proxy-model explanation.
Post by André Somers
Post by K. Frank
...
Post by K. Frank
...
I have a QTableView (backed by a QSqlTableModel) and am looking
for a simple way to make a column read-only.
...
...
In my case, I have only one view into the model, so I can use your
suggested approach to make (a column of) the model read-only.
But, for future reference, what's the best way to make the view
read-only? (For example, what if my application has two views
into the same model, only one of which should be read-only?)
You can use a proxy model to do that. There is a ready-made one that
http://qt-project.org/wiki/QSortFilterProxyModel_subclass_for_readonly_columns_columns_with_checkboxes_and_password_columns
Thank you. That's a good reference and a nice utility class.

Also, I think I'm getting a better sense now of how the Qt model
classes fit together.
Post by André Somers
If you have multiple views on a single model with different demands for
what column should be read-only, you can create multiple proxy models on
the same SQL model.
Yes, this addresses my (hypothetical) multiple-view issue.
Post by André Somers
One note on the wiki article: for Qt 4.8 and up, you should replace the
use of QSortFilterProxyModel with QIdentityProxyModel (as long as you
don't need filtering or sorting too, that is).
Yes. (Including those troglodytes, such as myself, who insist upon
using -- shudder -- a Release Candidate, 4.8.0-rc1!)

For the record, in my case I ended up building a read-only delegate
(that overrides createEditor to return NULL). So far it seems to work
fine.

I did it this way because using the delegate seems more view-ish, and
in my use case I think of the read-only attribute as being attached to
the view. (However, I don't really feel like I've fully absorbed the Qt
philosophy about where the model leaves off and the view begins.)

Also, the read-only delegate seems to me to be lighter weight (although
without knowing more about what is going on under the Qt hood, I may
be wrong about this).
Post by André Somers
André
Thanks again for your help.


K. Frank

Loading...