How to update a database from Qt?

0

I have a program that opens a database and presents the database through a model in a table view in Qt.

I am able to add and delete rows in my database through some buttons that activate the action and some text boxes where to put the information.

But now I want to be able to update the data directly from the table of my view, double click on a box, edit the data, and give enter to keep the change.

I can access the table box and edit the data, but I do not know how to do it so that when you enter that change is maintained. What can I do?

Here are the functions that I have in my model:

 Model_Sqlite(QObject *parent=nullptr);
    int rowCount(const QModelIndex &parent = QModelIndex()) const override ;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    void AddTableToDatabase ();
    void InsertData(QString theName);
    void DeleteRowID(int DataId);
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;

And here my function InsertData in which I implemented the text written in a QWidget LineEdit in the view to my database under the last inserted and updated the view.

void Model_Sqlite::InsertData(QString myName)
{
    //beginResetModel();
    int lastRow = rowCount() - 1;
    //int col = 0;
    QModelIndex theParentIndex = QModelIndex();
    beginInsertRows(theParentIndex, lastRow + 1, lastRow + 1);

    int numberOfLastValue=0;
    QSqlQuery qry;
    if(qry.exec("SELECT id from MyQtTable"))
    {
        qry.last();
        numberOfLastValue=qry.value(0).toInt();

        qDebug()<<"mis último id"<<numberOfLastValue;


    }
    else
    {
        qDebug()<<qry.lastError();
    }

    QSqlQuery query;
    query.prepare("INSERT INTO MyQtTable (id,name)"
                  "VALUES (:id, :name)");
    query.bindValue(":id", numberOfLastValue+1);
    query.bindValue(":name", myName);
    query.exec();

    //endResetModel();
    endInsertRows();
}

And here what I have tried to let you modify the data in the table of the view and that when you enter enter is kept in the database:

bool Model_Sqlite::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role !=Qt::EditRole){return false;}
    if (!index.isValid()){return false;}
    if (rowCount()<index.row()){return false;}
    if(columnCount()<index.column()){return false;}

        QSqlQuery qry;
        qry.prepare("SELECT MyQtTable.id, MyQtTable.name from MyQtTable ORDER BY MyQtTable.id");
        qry.exec();

//    QSqlQuery qry;
//    qry.prepare("SELECT id from MyQtTable");
//    qry.exec();
//    int themodifyID=qry.value(0).toInt();
//    qDebug()<<"The id modification"<< themodifyID;

//    QSqlQuery qry2;
//    qry2.prepare("SELECT id from MyQtTable");
//    qry2.exec();
//    QString themodifyName=qry.value(1).toString();
//    qDebug()<<"The name modification"<<themodifyName;

    int numRow = index.row();
        int numCol = index.column();
        qry.seek(numRow);

        QVariant theModification=qry.value(numCol);
        qDebug()<<theModification;
    // emit dataChanged(index,index);

    beginInsertRows(index, numRow , numRow);

    QSqlQuery query;
    query.prepare("INSERT INTO MyQtTable (id,name)"
                  "VALUES (:id, :name)");
    query.bindValue(":id",30 );
    query.bindValue(":name", "themodifyName");
    query.exec();

    endInsertRows();

    return true;

}

And here is an image that shows what the view is like.

    
asked by MAP 24.10.2018 в 08:08
source

1 answer

0

I was trying to change the information using INSERT INTO, en lugar de UPDATE '. I also did not know what indexes I was driving and where they came from, but solved !!

I leave here the function setData which is the one that I use to modify the data in the table of the view and that when I enter it remains stored in the database. I leave explanatory comments throughout the code to make it easier to follow what I have done.

bool Model_Sqlite::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role !=Qt::EditRole){return false;}
    if (!index.isValid()){return false;}
    if (rowCount()<index.row()){return false;}
    if(columnCount()<index.column()){return false;}

    QSqlQuery qry;
    qry.prepare("SELECT MyQtTable.id, MyQtTable.name from MyQtTable ORDER BY MyQtTable.id");
    qry.exec();

    // numRow y numCol me dan la posición del valor que quiero cambio en la tabla
    int numRow = index.row();
    int numCol = index.column();
    qry.seek(numRow);

    QVariant theModification=qry.value(numCol);             //obtengo el valor a cambiar
    qDebug()<<theModification;
    qDebug()<<numRow;                                       //fila de la tabla que cambio
    qDebug()<<value;                                        //valor nuevo escrito en la casilla

    QString oldName=qry.value(1).toString();                //capturo el nombre previo a ser modificado
    int oldId=qry.value(0).toInt();                         //capturo el id previo a ser modificado

    beginInsertRows(index, numRow , numRow);                //digo que solo me actualice fila de la casilla deseada

    if (numCol==0){
        //si el valor modificado esta en la columna 0 significa que tengo que cambiar el id
        QSqlQuery query;
        query.prepare("UPDATE MyQtTable SET Id=? WHERE Id=?");          //actualizo el viejo id por el nuevo id
        query.addBindValue(value);
        query.addBindValue(oldId);
        query.exec();
    }
    else if (numCol==1){
        //si el valor modificado esta en la columna 0 significa que tengo que cambiar el name
        QSqlQuery query;
        query.prepare("UPDATE MyQtTable SET name=? WHERE id=?");       //actualizo el nombre de la fila del id con el nuevo nombre   
        query.addBindValue(value);
        query.addBindValue(oldId);
        query.exec();
    }
    else
    {
        qDebug()<<"That column is not valid";
    }

    endInsertRows();
    emit dataChanged(index,index);                                      //envío la señal de datos modificados
    return true;
}
    
answered by 24.10.2018 / 09:06
source