Qt 模型/ View : how to handle underlying data properly

标签 qt model-view-controller qtableview qabstractitemmodel

我观看了大量的视频,并花了很多时间阅读有关模型的论文,如何使用它们以及总体思路非常清晰。然而,我仍然没有得到一些真正让我慢下来的事情。

我意识到模型仅作为 View 和数据之间的接口(interface)。但是,当我查看示例代码时,大多数时候,某种数据结构会发送到模型,并且模型中的所有函数都使用该内部模型数据结构来执行所需的操作:评估标题、行数等。此类示例构造函数(在本例中,内部模型 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));
}

这看起来不错,但是当我尝试考虑修改程序中其他地方的基础数据时,当某种模型“附加”到该数据结构时,它会变得非常困惑。

例如,让我们看一下学习 Material 中的示例代码:

    // 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。现在,用户将能够查看和修改该数据。但是,如果我想在程序的其他地方更多地处理这些数据怎么办?如果我向地址插入新条目会怎样?我意识到模型不会看到这些更改,并且在这个示例(以及更多示例)中,底层数据结构甚至不是作为指针发送的。

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

最佳答案

使用 Qts 数据模型可能会非常令人困惑。您将需要处理您自己的大部分“更新”。例如,如果您在 QAbstractItemModel::setData 重载中更改模型数据,则必须自行发出 QAbstractItemModel::dataChanged 。插入、删除或移动条目也是如此。如果您有时间,您应该阅读 SaZ 发布的链接,但是有关在哪个重载中发出什么内容的一些快速信息,您可以检查 QAbstractItemModel Documentation .

关于“在幕后”修改数据: 最佳实践是更改模型上的数据,即调用 QAbstractItemModel::setData 来更改一些数据。但由于此函数旨在以“可显示格式”获取数据,因此如果您创建自己的函数,效果会更好。在此函数内部,您需要“通知”模型您的更改。这样所有 View 都会正确更新。

例如,如果您的“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 模型- View 框架可能非常棘手,特别是当您必须添加、删除、移动或排序数据时。但要想更深入地了解它,恐怕你必须尝试一下!

关于Qt 模型/ View : how to handle underlying data properly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33106254/

相关文章:

c++ - QTableview 属性

c++ - 在 QTableView 中设置 QPlainTextEdit 委托(delegate)的高度

python - PyInstaller 打包的应用程序在控制台模式下工作正常,在窗口模式下崩溃

c++ - 为什么 _WIN32_WINNT == 0x400 在 Windows 7 机器上的 Qt Creator 中?

c++ - 如何强制调整 indexWidgets 的大小以适应 Qt5 QTableView 的单元格

wpf - WPF 的 MVC(不是 mvvm)?

asp.net-mvc - 是否可以删除 .Net Web Api 应用程序中的所有 .Net MVC 组件,以便我可以使用 AngularJS 作为前端?

c++ - qInstallMessageHandler 不接受公共(public)方法作为参数

c++ - 调整网格布局内的标签大小?

Java MVC - 感觉我不明白