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

Editing data in QStandardItemModel (and tableview)



  • Hi,
    I have a standarditemmodel.

    QStandardItemModel *fixModel = new QStandardItemModel(this);
    ui->tableView_Fix->setModel (fixModel);
    

    I want to allow the user to edit items in the model so I added the following:

      ui->tableView_Fix->setEditTriggers (QAbstractItemView::DoubleClicked);
    
    

    It allow editing but doesn't save the edited version. What should I do to get the model to save the changed data? Thank you.



  • I don't see anything wrong with your code and QStandardItemModel supports editing. do you use a custom delegate?



  • @VRonin
    Hi,
    I don't use custom delegate. My theory was to use setedittriggers and it should save the changes, but it does not.



  • @VRonin
    Here is the .h and .cpp:
    fixdb.h:

    #ifndef FIXDB_H
    #define FIXDB_H
    
    #include <QDate>
    #include <QDialog>
    #include <QPixmap>
    #include <QStandardItemModel>
    #include <QString>
    #include <QSqlError>
    #include <QSqlTableModel>
    #include <QSqlQuery>
    #include <QSqlRecord>
    #include <QTableView>
    
    namespace Ui
    {
    class FixDb;
    }
    
    class FixDb : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit FixDb(QWidget *parent = 0);
        ~FixDb();
        void correctFriend();
    
    
    
    // QString
        QString date;
        QString monthf;
        QString dayf;
        QString yearf;
    
    //int
        int col;
    
    //Pixmap
        QPixmap fixPixmap;
    
    private slots:
    
    
    private:
        Ui::FixDb *ui;
    };
    
    #endif // FIXDB_H
    
    

    fixdb.cpp:

    #include "fixdb.h"
    #include "ui_fixdb.h"
    #include <QDebug>
    
    FixDb::FixDb(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::FixDb)
    {
        ui->setupUi(this);
    
        correctFriend ();
    }
    
    FixDb::~FixDb()
    {
        delete ui;
    }
    
    void FixDb::correctFriend()
    {
        QSqlQuery query_fix ("SELECT * FROM Items ORDER BY name asc");
    
        if(query_fix.isActive () == true)
            {
                qDebug() << "The query_fix is active!";
            }
        else
            {
                qDebug() << "The query_fix is NOT active!" << query_fix.lastError ();
            }
    
        QStandardItemModel *fixModel = new QStandardItemModel(this);
        ui->tableView_Fix->setModel (fixModel);
    
        for(int row1 = 0; query_fix.next (); row1++)
            {
                if(row1 == 0)
                    {
                        const QSqlRecord qRec = query_fix.record();
                        qDebug() << "The number of records (MainWindow): " << qRec;
                        fixModel->insertColumns (0, (qRec.count()-2));
                    }
    
                fixModel->insertRow (row1);
                fixModel->setData (fixModel->index (row1,0),query_fix.value (0));
                fixModel->setData (fixModel->index (row1,1),query_fix.value (1));
                fixModel->setData (fixModel->index (row1,2), query_fix.value (13));
    
                fixPixmap.loadFromData (query_fix.value (2).toByteArray ());
                fixPixmap = fixPixmap.scaled (100,100,Qt::KeepAspectRatio);
    
                fixModel->setData (fixModel->index (row1,3),fixPixmap,Qt::DecorationRole);
                fixModel->setData (fixModel->index (row1,4),query_fix.value (11));
                fixModel->setData (fixModel->index (row1,5),query_fix.value (10));
                fixModel->setData (fixModel->index (row1,6),query_fix.value (3));
                fixModel->setData (fixModel->index(row1,7),QDate(query_fix.value (6).toInt(),query_fix.value (4).toInt(),query_fix.value (5).toInt()));
                fixModel->setData (fixModel->index (row1,8),query_fix.value (12));
                fixModel->setData (fixModel->index (row1,9),query_fix.value (7));
                fixModel->setData (fixModel->index (row1,10),query_fix.value (8));
                fixModel->setData (fixModel->index (row1,11),query_fix.value (9));
    
                ui->tableView_Fix->setRowHeight (row1,100);
            }
    
        ui->tableView_Fix->horizontalHeader ()->setStyleSheet ("QHeaderView{font: 14pt Arial; color: blue; font-weight: bold; text-decoration: underline;}");
        ui->tableView_Fix->verticalHeader ()->setVisible (false);
        ui->tableView_Fix->setAlternatingRowColors (true);
        ui->tableView_Fix->setStyleSheet ("alternate-background-color: rgb(224,255,248); background-color: white; font: 14pt Arial; ");
        ui->tableView_Fix->setEditTriggers (QAbstractItemView::DoubleClicked);
    
    
        fixModel->setHeaderData (0,Qt::Horizontal, QObject::tr ("ID"));
        fixModel->setHeaderData (1,Qt::Horizontal, QObject::tr ("Name"));
        fixModel->setHeaderData (2,Qt::Horizontal, QObject::tr ("What"));
        fixModel->setHeaderData (3,Qt::Horizontal, QObject::tr ("Image"));
        fixModel->setHeaderData (4,Qt::Horizontal, QObject::tr ("Material"));
        fixModel->setHeaderData (5,Qt::Horizontal, QObject::tr ("Color"));
        fixModel->setHeaderData (6,Qt::Horizontal, QObject::tr ("Description"));
        fixModel->setHeaderData (7,Qt::Horizontal, QObject::tr ("Adoption Date"));
        fixModel->setHeaderData (8,Qt::Horizontal, QObject::tr ("Signed by"));
        fixModel->setHeaderData (9,Qt::Horizontal, QObject::tr ("History"));
        fixModel->setHeaderData (10,Qt::Horizontal, QObject::tr ("Age"));
        fixModel->setHeaderData (11,Qt::Horizontal, QObject::tr ("Notes"));
    
        ui->tableView_Fix->setColumnWidth (0,60);
        ui->tableView_Fix->setColumnWidth (1,120);
        ui->tableView_Fix->setColumnWidth (2,150);
        ui->tableView_Fix->setColumnWidth (3,100);
        ui->tableView_Fix->setColumnWidth (4,130);
        ui->tableView_Fix->setColumnWidth (5,120);
        ui->tableView_Fix->setColumnWidth (6,400);
        ui->tableView_Fix->setColumnWidth (7,150);
        ui->tableView_Fix->setColumnWidth (8,200);
        ui->tableView_Fix->setColumnWidth (9,400);
        ui->tableView_Fix->setColumnWidth (10,130);
        ui->tableView_Fix->setColumnWidth (11,300);
    
        ui->tableView_Fix->setWordWrap (true);
    
    }
    
    

  • Lifetime Qt Champion

    Hi,

    By save, do you mean in your QStandardItemModel object or in the database ?



  • @SGaist
    Hi,
    My bad. I ment the db.



  • ok, this is a whole different matter.

    You have to connect a slot to dataChanged of the model and execute a query to update the db



  • @VRonin
    I'm trying to implement the slot and query.
    I have the following for connect:

    connect(fixModel, SIGNAL(fixModel->dataChanged),this, SLOT(refreshDb()));
    

    For updating the db:

        QSqlQuery query_update;
        query_update.prepare ("UPDATE Items SET ID = :fixID");
        query_update.bindValue (":fixID",ID);
    

    Assuming this works (wasn't able to test it yet). To make this work, I need to get the ID from column 0 of tableview. I try to use this:

        QModelIndex fixIndex(index.model ()->index.fixRow(),0,index.parent ());
        qDebug() << fixIndex.data (Qt::DisplayRole);
        QVariant vfix(fixIndex.data(Qt::DisplayRole));
        fixID = vfix.toString ();
        qDebug() << "fixID: " << fixID;
    

    but the first line gives me an error:
    C:\Programming\Projects\Folkfriends_1_0\fixdb.cpp:124: error: '(& index)->QModelIndex::model()->QAbstractItemModel::index' does not have class type
    QModelIndex fixIndex(index.model ()->index.fixRow(),0,index.parent ());
    ^
    What did I miss?
    Thank you.



  • Are you in a hurry? looks like it...

    connect(fixModel, SIGNAL(fixModel->dataChanged),this, SLOT(refreshDb())); makes no sense. the SIGNAL argument is completely wrong and both miss the arguments...

    index.model ()->index makes no sense. index.row() is what you need



  • @VRonin
    I think I need to emit an itemChanged signal and it has to receive by the function which will process the db update.
    I came up with the following, but it is still not working:

     connect(fixModel ,SIGNAL(itemChanged), this, SLOT(updateItem(itemChanged)));
    

    How can I emit the itemChanged signal correctly? I get the error message
    "QObject::connect: Parentheses expected, signal QStandardItemModel::itemChanged in ..\Folkfriends_1_0\fixdb.cpp:107"
    Thank you


  • Lifetime Qt Champion

    Both your SIGNAL and SLOT macro content is wrong.

    You really should use the syntax as described here. It will avoid such errors.



  • @SGaist
    I try to use the sample .
    It creates a 2 dimensional array QString m_gridData[ROWS][COLS] to hold the text entered into QTableView. This requires me to know the number of rows and columns. Is there any way I can get the text entered not using an array? Thank you.


  • Lifetime Qt Champion

    QVector< QVector<QString> > m_gridData;



  • @SGaist
    I try to understand how to work this QVector. I believe your code includes 2 QVectors. I think what I'm trying to do is adding 2 int (the row and col) to the vector plus the QString stored at the location defined by the 2 int. Would you please show me how to do that? Thank you.


  • Lifetime Qt Champion

    @gabor53
    Hi To get the string, you need to know row, col so why you need to store it with string ?

    Anyway, you can use a struct
    struct MyData {
    QString data;
    int col;
    int row;
    };

    QVector< QVector<MyData> > m_gridData;

    Notice !
    unlike
    QString m_gridData[ROWS][COLS];

    QVector is EMPTY to start with so you must append before you can access.


  • Lifetime Qt Champion

    Or if you know the initial size your can fill your QVector of QVector are startup.


Log in to reply