Search code examples
c++qtqtreeviewqstandarditemmodel

Manipulating data in a QStandardItemModel/QTreeView?


In my project, I parse a data file and create a QStandardItemModel based off that file which is then displayed in a QTreeView. The model gets created fine and I know how to set certain parameters for each QStandardItem when it is created. For example, I know how to set the display text and the icon. Is there a way I can create "custom containers" for storing "extra" data in each item?

READING from a data file and parsing it into a model I (believe) I can do just fine. However the user needs to be able to edit/manipulate the model from within the QTreeView. This includes adding and removing items. This seems simple enough HOWEVER, some of the data associated with that item is NOT displayed in the QTreeView. It's kinda... "hidden" until the user tries to edit it. The user needs to double-click on an item to bring up a dialog where they can edit a whole bunch of other parameters and data (Like really long strings and stuff, stuff I can't just display in the QTreeView).

I'm having significant difficulties trying to find a way to store all the "extra data" pertaining to each item in the tree. Initially, a QVector of sorts pops into mind, however manipulating the model while also manipulating the QVector is a technique I just can't wrap my head around.

To make things even worse, the user needs to be able to switch between different data files (aka models) while still retaining any edits made to the previous data file.

Any ideas? If you have any questions, don't hesitate to ask. I can clarify as much as you want. :) Thanks for your time.


Solution

  • The answer is yes, you can store additional data. You need to setData() to the specific user role + 1. For example:

    view->model()->setData(someIndex,"New Data", Qt::UserRole + 1);
    

    To get this data use data() method and same role. For editing this you can also try to use custom dialog or custom delegate.

    QVariant can use containers such as QList or QStringList, so you can use containers too. For example:

    auto in = ui->tableView->model()->index(0,0);
    QList<QVariant> lst;
    lst << "one" << "two" << "three";
    view->model()->setData(in,QVariant(lst),Qt::UserRole+1);
    //...
    qDebug() << "output:"<<view->model()->data(in,Qt::UserRole+1).toList();
    

    Output:

    output: (QVariant(QString, "one") , QVariant(QString, "two") , QVariant(QString, "three") )