Qt模型/视图:如何正确处理基础数据

时间:2015-10-13 15:08:40

标签: qt model-view-controller qtableview qabstractitemmodel

我观看了大量的视频,花了很多时间阅读有关模型的论文,如何使用它们,一般的想法非常明确。但是,我仍然没有得到一些让我失望的东西。

我意识到该模型仅作为视图和数据之间的接口。但是,当我查看示例代码时,大多数情况下,某种数据结构被发送到模型,模型中的所有函数都使用该内部模型数据结构来执行所需的操作:评估标题,行数等。此类示例构造函数(在这种情况下,内部模型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添加新条目怎么办?我意识到模型不会看到这些变化,并且在这个例子中(以及更多),底层数据结构甚至不是作为指针发送的。

所以我的问题是:如何正确管理数据,何时我会在幕后发布新数据&#34; - 不仅来自模特?我应该只在模型类中使用数据管理(实现所需的功能等)吗?我应该以某种方式仅将数据指针传递给模型吗?当我想到使用代理模型进行过滤时,一切都变得更加棘手,因为它们也可以工作并且有点“处理”#34;数据以自己的方式。也许我错过了一些关于这个架构的重要信息,但它真的让我不知所措。

1 个答案:

答案 0 :(得分: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框架可能非常棘手,特别是如果你必须添加,删除,移动或排序数据。但为了更深入地了解它,我担心你只需要试一试!