Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt Model/View: how to handle underlying data properly

I watched tons of videos and spent a lot of time reading papers about models, how to work with them and general idea is quite clear. However, I still don't get several things that really slow me down.

I realize that model works only as an interface between view and data. However, when I look at sample codes, most of the time, some sort of data structure is sent to model and all functions in the model uses that internal model data structure to do required things: evaluate headers, row count etc. Example of such constructor (in this case internal model QList is 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));
}

And that looks OK, but it gets very confusing when I try to think about modifying underlying data some where else in the program, when some sort of model is "attached" to that data structure.

For example, lets have a look at this sample code from learning 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();
}

Here, there is a static variable of addresses which is then sent to model. Now, user would be able to see and modify that data. But what if I want to work more with that data somewhere else in the program? What if I insert new entries to addresses? I realize that model will not see those changes, and in this example (and in many more) that underlying data structure is even sent not as a pointer.

So my question is: how to manage data properly, when I will have new data coming from "behind the scenes" - not only from the model? Should I work with data management only within the model class (implement required functions etc.)? Should I somehow pass only pointers of data to model? Everything gets even more tricky, when I think of using Proxy Models for filtering, because they also work and somewhat "treat" data in their own way. Maybe I missed something important about this architecture, but it really stops me here.

like image 535
rofl Avatar asked Dec 20 '25 21:12

rofl


1 Answers

Working with Qts data models can be quite confusing. You will need to take care of most of the "updates" of you own. For example, if you change the models data in your overload of QAbstractItemModel::setData, you will have to emit QAbstractItemModel::dataChanged on your own. Same goes for inserting, removing or moving entries. If you have the time, you should read the link posted by SaZ, but for some quick information about what to emit in which overload, you can check the QAbstractItemModel Documentation.

Regarding the modifying of data "behind the scenes": Best practice is to change the data over your model, i.e. call QAbstractItemModel::setData to change some data. But since this function is designed to get data in a "displayable format", your better of if you create your own functions. Inside of this functions you will need to "notify" the model of your changes. This way all Views will updater properly.

For example, if your "AddressRecord" has a name property:

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

As you can see, you will have to somehow work with the QModelIndex-class, which represents the position of an entry inside your model.

I hope I could help at least a little bit, but Qts Model-View framework can by very tricky, especially if you have to add, remove, move or sort your data. But to get a deeper understanding of it, I'm afraid you will just have to try it out!

like image 87
Felix Avatar answered Dec 24 '25 11:12

Felix



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!