2015-10-13 2 views
0

Я смотрел тонны видео и проводил много времени, читая статьи о моделях, о том, как работать с ними и общая идея, совершенно ясна. Тем не менее, я все еще не получаю несколько вещей, которые меня действительно мешают.Qt Model/View: как правильно обрабатывать базовые данные

Я понимаю, что модель работает только как интерфейс между представлением и данными. Однако, когда я смотрю на примеры кода, большую часть времени на модель отправляется какая-то структура данных, и все функции в модели используют эту внутреннюю структуру данных модели для выполнения необходимых действий: оценивают заголовки, количество строк и т. Д. Пример таких конструктор (в этом случае внутренняя модель QList является addressBook):

AddressbookModel::AddressbookModel(const QString& addresses, 
    QObject *parent): QAbstractTableModel(parent) 
{ 
    QStringList records = addresses.split(’\n’); 
    QStringList line; 
    foreach(QString record, records) 
    addressBook.append(splitCSVLine(record)); 
} 

И это выглядит нормально, но это становится очень запутанным, когда я пытаюсь думать об изменении исходных данных, где некоторые еще в программе, когда какой-то модели «привязан» к этой структуре данных.

Например, давайте посмотрим на этот пример кода из учебного материала:

// addressbook/main.cpp 
#include <QtGui> 
#include "addressbookmodel.h" 
int main(int argc, char* argv[]) 
{ 
    QApplication app(argc, argv); 
    QFile file("addressbook.csv"); 
    if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) 
    return 1; 
    QString addresses = QString::fromUtf8(file.readAll()); 
    AddressbookModel model(addresses); 
    QTableView tableView; 
    tableView.setModel(&model); 
    tableView.show(); 
    return app.exec(); 
} 

Здесь есть статическая переменная addresses, которая затем отправляется в model. Теперь пользователь сможет просматривать и изменять эти данные. Но что, если я хочу больше работать с этими данными в другом месте программы? Что делать, если я вставляю новые записи в addresses? Я понимаю, что модель не увидит эти изменения, и в этом примере (и во многих других), что базовая структура данных даже отправляется не как указатель.

Так что мой вопрос: как правильно управлять данными, когда у меня будут новые данные, поступающие из «за кулисами» - не только из модели? Должен ли я работать с управлением данными только в классе модели (реализовать требуемые функции и т. Д.)? Должен ли я каким-то образом передавать только указатели данных на модель? Все становится еще более сложным, когда я думаю об использовании прокси-моделей для фильтрации, потому что они также работают и несколько «обрабатывают» данные по-своему. Возможно, я пропустил что-то важное в этой архитектуре, но меня это действительно останавливает.

+0

Вы должны начать здесь: http://doc.qt.io/qt-5/model-view-programming.html –

+0

Хорошо, я попытаюсь взглянуть на эту страницу. Хотя я думаю, что видел многих из них, но этот выглядит шире. – rofl

ответ

1

Работа с моделями данных Qts может быть довольно запутанной. Вам нужно будет позаботиться о большинстве ваших «обновлений». Например, если вы измените данные моделей в своей перегрузке QAbstractItemModel::setData, вам придется выпустить QAbstractItemModel::dataChanged самостоятельно. То же самое касается вставки, удаления или перемещения записей. Если у вас есть время, вы должны прочитать ссылку, опубликованную SaZ, но для получения некоторой быстрой информации о том, что испускать, при перегрузке, вы можете проверить QAbstractItemModel Documentation.

Что касается изменения данных «за кулисами»: Лучшей практикой является изменение данных по вашей модели, то есть вызов QAbstractItemModel::setData для изменения некоторых данных. Но поскольку эта функция предназначена для получения данных в «отображаемом формате», вам лучше, если вы создадите свои собственные функции. Внутри этих функций вам необходимо «уведомить» модель ваших изменений. Таким образом, все представления будут корректно обновляться.

Например, если ваш «AddressRecord» имеет name свойство:

void AddressbookModel::changeName(QModelIndex addressIndex, QString name) { 
    //For this example I assume you are using a simple list model with only one column 
    //The addressIndex´s column is always 0 in this case, and the parent invalid 
    addressBook[addressIndex.row()].setName(name); 
    emit dataChanged(addressIndex, addressIndex); 
} 

Как вы можете видеть, вам придется как-то работать с QModelIndex -класса, который представляет положение записи внутри вашей модель.

Надеюсь, что я смогу помочь хотя бы немного, но структура Qts Model-View может быть очень сложной, особенно если вам нужно добавлять, удалять, перемещать или сортировать данные. Но чтобы получить более глубокое понимание этого, я боюсь, вам просто нужно попробовать!

+0

Спасибо, очень признателен за ваш ответ, но как все это относится к ситуациям, когда используются прокси-модели? Они работают как обертки моделей, поэтому, когда я пишу всю логику обработки данных в исходной модели, могу ли я по-прежнему использовать прокси-модели с таким подходом к обработке данных? Насколько я помню, я установил прокси-модель для представления, а не исходную модель. – rofl

+0

Точно! Если вы правильно измените данные в исходной модели, прокси-модель будет уведомлена об этих изменениях и сделает все, для чего она предназначена. (например, сортировать, фильтровать, ...) и уведомлять о представлении изменений, сгенерированных ими в исходной модели. Конечно, реализация прокси-модели также должна быть правильной. – Felix

Смежные вопросы