Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QAbstractTableModel: Storing information that is not shown by the QTableView



  • I have followed the Address Book Example to create my own TableModel and TableView.

    My implementation is very similar to this example, except each entry in the table is a Patient struct that has an ID associated with it. This ID is not shown the TableView, but when modifications are made, I use the ID to save the changes in the filesystem.

    This is the MyPatient struct

    struct MyPatient
    {
        qlonglong id;
        QString firstName;
        QString lastName;
        QString dob;
        QString sex;
        QString height;
        QString weight;
        QString dateModified;
    
        bool operator==(const MyPatient &other) const
        {
            return id == other.id;
        }
    };
    

    Here is the body of my addPatient() method to add a patient to the table:

    insertRows(0, 1, QModelIndex());
    
    QModelIndex index = this->index(0, 0, QModelIndex());
    setData(index, patient.firstName, Qt::EditRole);
    index = this->index(0, 1, QModelIndex());
    setData(index, patient.lastName, Qt::EditRole);
    index = this->index(0, 2, QModelIndex());
    setData(index, patient.dob, Qt::EditRole);
    index = this->index(0, 3, QModelIndex());
    setData(index, patient.sex, Qt::EditRole);
    index = this->index(0, 4, QModelIndex());
    setData(index, patient.height, Qt::EditRole);
    index = this->index(0, 5, QModelIndex());
    setData(index, patient.weight, Qt::EditRole);
    index = this->index(0, 6, QModelIndex());
    setData(index, patient.dateModified, Qt::EditRole);
    

    With the current implementation, when I call the data() method to retrieve a patient, the ID field is 0, because the table does not store that value.

    How can I store this ID value in the table without showing it as its own column in the TableView?

    I have tried added another two lines to the addPatient method:

        index = this->index(0, 7, QModelIndex());
        setData(index, patient.id, Qt::EditRole);
    

    But the setData detects the index value as invalid, as the columnCount of the table is 7 as that is how many columns should appear in the QTableView.

    Thank you, please let me know if there is anything in my question I can clarify.


  • Lifetime Qt Champion

    Hi
    You can store the data in a user Role. ( for any existing column)
    setData(index, patient.id, Qt::UserRole);
    or you could have it as a real column
    and simply hide it. (in the view)
    TableView->setColumnHidden(7, true);



  • I had assumed the intended way is QTableView::hidden(). This allows the column to appear naturally in the model and be manipulated as such. I'm trying to figure what @mrjj 's alternative of storing it in a user role adds up to....


  • Lifetime Qt Champion

    @JonB
    Hi
    Well its just like Qt::EditRole, but not shown by the View. However can be used
    by delegates etc.



  • @mrjj said in QAbstractTableModel: Storing information that is not shown by the QTableView:

    Hi
    You can store the data in a user Role. ( for any existing column)
    setData(index, patient.id, Qt::UserRole);
    or you could have it as a real column
    and simply hide it. (in the view)
    TableView->setColumnHidden(7, true);

    Can QTableView use the roleNames interface that TableView in QML requires? Or are QTableView and TableView very different?


  • Lifetime Qt Champion

    @fcarney
    Hi
    I dont know if thats the same between QWidgets and QML
    https://doc.qt.io/qt-5/qabstractitemmodel.html#roleNames


  • Lifetime Qt Champion

    Hi,

    @smiffy Might be silly question but did you check that your patient.id value is valid ?

    @fcarney What do you have in mind with QTableView and the custom roles ?



  • @SGaist said in QAbstractTableModel: Storing information that is not shown by the QTableView:

    @fcarney What do you have in mind with QTableView and the custom roles ?

    When I tried to create an interface for both a QTableView and a TableView it seemed like I had to implement different things to get them to work. I was wondering if there was a common way to interface to either set of views. If the answer is just "they are different" I am fine with that.


  • Lifetime Qt Champion

    Until 5.12, they are different. However, you can map the column/role names in the data function and you're good to go for both situations.

    [edit: Fixed missing Qt version precision SGaist]



  • I have followed the Address Book Example to create my own TableModel

    If you are creating your custom model, why don't you just store the MyPatient items directly and just reimplement data() to return the field you prefer?

    @fcarney said in QAbstractTableModel: Storing information that is not shown by the QTableView:

    When I tried to create an interface for both a QTableView and a TableView it seemed like I had to implement different things to get them to work.

    TL;DR: from Qt 5.12 onward QTableView and TableView can be used with almost no change in the interface

    This is currently changing. The QML tableview used to be basically multiple listviews squashed together, it's now evolving https://blog.qt.io/blog/2018/08/29/tableview/ and a treeview is also in the pipeline.


Log in to reply