Как сделать постоянную правильную архитектуру модель / представление только для чтения в Qt? - PullRequest
2 голосов
/ 03 апреля 2012

Предположим, я хочу реализовать архитектуру модель / представление с использованием классов QTableView и QAbstractTableModel. Поэтому я создаю подкласс QAbstractTableModel для создания класса MyModel и реализации интерфейса QAbstractTableModel. Затем подключите экземпляр этой модели к экземпляру QTableView, используя метод setModel.

 #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();
 }

Но как я могу сделать модель доступной только для чтения? Я не могу объявить

const MyModel myModel(0);

потому что setModel принимает непостоянный аргумент. Я переопределил только постоянные методы QAbstractTableModel.

Ответы [ 3 ]

5 голосов
/ 03 апреля 2012

Что вы подразумеваете под const в данном случае? Чего ты хочешь достичь?

Хотите ли вы, чтобы ваши базовые данные были неизменяемыми - чтобы издание с QTableView было невозможно? Тогда просто запретите редактирование модели - например, не реализуя setData.

Также обратите внимание, что стандартная реализация из

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

не вернет Qt::ItemIsEditable, что достаточно.

Вы должны позаботиться о том, чтобы не изменять модель вне пользовательского интерфейса (обратите внимание, что изменение ее снаружи без отправки соответствующих сигналов может привести к плохим вещам ). Но поскольку это ваш код - это не должно быть проблемой.

2 голосов
/ 03 апреля 2012

Что ж, в предположении, что вы имеете в виду только чтение для конечного пользователя, а не только для чтения программистом, эта статья объясняет, что модель доступна для редактирования только при повторной реализации QAbstractItemModel::flags(), QAbstractItemModel::setData() и, что не менее важно QAbstractItemModel::setHeaderData().

Кроме того, функции, которые необходимо переопределить для модели только для чтения, : 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 { }
2 голосов
/ 03 апреля 2012

Нельзя сделать модель постоянной, поскольку есть вещи, которые представления должны иметь, которые могут повлиять на объект QAbstractItemModel, например создание постоянных модельных индексов.

Лучший способ сообщить фактчто ваша модель доступна только для чтения, переопределив QAbstractTableModel::flags, чтобы всегда сбрасывать ItemIsEditable:

Qt::ItemFlags MyModel::flags ( const QModelIndex & index ) const
{
    return QAbstractTableModel::flags(index) & ~Qt::ItemIsEditable;
}
...