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.


  • Qt Champions 2016

    @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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.