2

Suppose I want to implement a model/view architecture using the QTableView and QAbstractTableModel classes. So I subclass the QAbstractTableModel to create class MyModel and implement the QAbstractTableModel interface. Then connect the instance of this model to a QTableView instance using the setModel method.

 #include <QtGui/QApplication>
 #include <QtGui/QTableView>
 #include "mymodel.h"

 int main(int argc, char *argv[])
 {
     QApplication a(argc, argv);
     QTableView tableView;
     MyModel myModel(0);       
     tableView.setModel( &myModel );
     tableView.show();
     return a.exec();
 }

But how can I make the model read only? I cannot declare

const MyModel myModel(0);

because setModel takes a non constant argument. I reimplemented only constant methods of QAbstractTableModel.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146

3 Answers3

5

What do you mean by const in this case? What do you want to achieve?

Do you want your underlying data to be immutable - so that edition from QTableView would be impossible? Then just disallow editing the model - e.g. by not implementing setData.

Also note that the standard implementation of

Qt::ItemFlags QAbstractItemModel::flags ( const QModelIndex & index ) const

will not return Qt::ItemIsEditable which is sufficient.

You will have to take care not to modify the model outside of the UI (note that modifying it outside without sending appropriate signals can result in bad things). But as it is your code - this shouldn't be an issue.

Anonymous
  • 18,162
  • 2
  • 41
  • 64
  • I just want to be able to pass the model from another object using a constant method of that object. It is not a big issue, but once I make some method not constant, when it is supposed to be constant, then this spreads also to other methods using this method. – Martin Drozdik Apr 03 '12 at 08:00
  • 1
    I have seen Qt code that dealt with such issue using the brutal `const_cast` method. Not that elegant, potentially dangerous, but... – Anonymous Apr 03 '12 at 08:40
2

You can't make the model constant, as there are things that views need to be able to do that affect the QAbstractItemModel object, such as creating persistent model indexes.

The best way to communicate the fact that your model is read-only to the view is by overriding QAbstractTableModel::flags to always unset ItemIsEditable:

Qt::ItemFlags MyModel::flags ( const QModelIndex & index ) const
{
    return QAbstractTableModel::flags(index) & ~Qt::ItemIsEditable;
}
je4d
  • 7,628
  • 32
  • 46
2

Well on the assumption you mean read only by the end-user, and not read-only by the programmer, this article explains that the model is only editable when you re-implement QAbstractItemModel::flags(), QAbstractItemModel::setData(), and less importantly QAbstractItemModel::setHeaderData().

Furthermore, the functions you need to reimplement for a read only model, are all const:

Qt::ItemFlags TreeModel::flags(QModelIndex const & index) const { }
QModelIndex TreeModel::index(int row, int column, QModelIndex const & parentIndex) const { }
QModelIndex TreeModel::parent(QModelIndex const & childIndex) const { }
QVariant TreeModel::data(QModelIndex const & index, int role) const { }
QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { }
int TreeModel::rowCount(QModelIndex const & parent) const { }
int TreeModel::columnCount(QModelIndex const & parent) const { }
Samuel Harmer
  • 4,264
  • 5
  • 33
  • 67