How To Change data (setData) in EditableModel child on QSqlQueryModel ?



  • this is mainwindow:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "editablemodel.h"
    #include "QSqlQuery"
    #include "QDebug"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        func();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::refresh(){
        ui->ccc->setText("start");
    }
    
    void MainWindow::func(){
        amdb = QSqlDatabase::database("connect");
    
        if(amdb.isOpen()){
            qDebug() << amdb.databaseName();
        }else{
            qDebug() << "NO";
        }
    
        QSqlQuery query(amdb);
    
        query.prepare("SELECT * FROM valuta");
    
        query.exec();
    
        model->setQuery(query);
    
        model->setHeaderData(0, Qt::Horizontal, tr("იდი"));
        model->setHeaderData(1, Qt::Horizontal, tr("ვალუტის სახელი"));
        model->setHeaderData(2, Qt::Horizontal, tr("ფუნქცია"));
    
        ui->tableView->setModel(model);
        ui->tableView->verticalHeader()->hide();
        ui->tableView->setColumnWidth(1,170);
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        qDebug() << ui->ccc->text();
    }
    
    

    this ediatblemodel:

    #include "editablemodel.h"
    #include "QSqlQueryModel"
    #include "QSqlQuery"
    #include "mainwindow.h"
    #include "QDebug"
    
    EditAbleModel::EditAbleModel(QObject *parent) : QSqlQueryModel(parent)
    {
    
    }
    
    Qt::ItemFlags EditAbleModel::flags(
            const QModelIndex &index) const
    {
        Qt::ItemFlags flags = QSqlQueryModel::flags(index);
        if (index.column() == 0 || index.column() == 2)
            flags |= Qt::ItemIsEditable;
        return flags;
    }
    
    bool EditAbleModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
    {
        if (index.column() < 1 || index.column() > 2)
            return false;
    
        QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(),0);
        int id = data(primaryKeyIndex).toInt();
    
    //    qDebug() << index.row() << " " << index.column() << "aaaa"<<endl;
    
        bool ok;
        if (index.column() == 1) {
            ok = setFirstName(id, value.toString());
        } else {
            ok = setLastName(id, value.toString());
        }
    
    //    MainWindow* w = new MainWindow();
    
    //    emit run();
    
    //    connect(this,SIGNAL(run()),w,SLOT(refresh()));
    
        return ok;
    }
    
    void EditAbleModel::refresh()
    {
     **DONT NEED THIS!!!!**
    }
    
    bool EditAbleModel::setFirstName(int personId, const QString &firstName)
    {
        QSqlQuery query;
        query.prepare("update valuta set main = '1' where uid = '4'");
        query.addBindValue(firstName);
        query.addBindValue(personId);
        return query.exec();
    }
    
    bool EditAbleModel::setLastName(int personId, const QString &lastName)
    {
        QSqlQuery query(amdb);
    
        qDebug() << personId << " " << lastName << endl;
    
        int lst = lastName.toInt();
    
        query.prepare("update valuta set main = :one where uid = :two ");
        query.bindValue(":one",lst);
        query.bindValue(":two",personId);
        return query.exec();
    }
    
    

    this main.cpp:

    #include "mainwindow.h"
    #include <QApplication>
    #include "QSqlDatabase"
    #include "QFileInfo"
    #include "QDebug"
    
    QSqlDatabase amdb;
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        amdb = QSqlDatabase::addDatabase("QSQLITE", "connect");
    
        amdb.setDatabaseName("C:/Users/tleladze/Desktop/valuta/VALUTA.sqlite");
    
        amdb.open();
    
        MainWindow w;
    
        w.show();
    
        return a.exec();
    }
    
    


  • I dont want refresh all database :(


  • Qt Champions 2016

    @Taz742
    Hi
    Its a bit unclear what actual error is.
    It does save new data to database but the view is not showing it ?
    Or which part is not working for you ?


  • Lifetime Qt Champion

    Hi,

    To add to @mrjj, the implementation of setFirstName looks suspicious. You seem to want to use positional placeholders while your query isn't written for that.



  • @mrjj Yes, it saves new data in database but form shows old numbers


  • Qt Champions 2016

    @Taz742

    Ok, maybe you need to use the
    http://doc.qt.io/qt-5/qabstractitemmodel.html#rowsAboutToBeRemoved
    or some other function that fits the action you do to the data.

    Currently, you just change the database behind its back
    so I guess what is wrong is that it cannot know that. :)



  • @mrjj
    It does not have setQuery();


  • Lifetime Qt Champion

    QAbstractItemModel is the lowest base class of QSqlQueryModel.



  • @SGaist
    you are right.

    So, I think it would be better TableWidget. I fill in the data manually.

    What do you think? @SGaist , @mrjj



  • I solved my problem.

    QSqlQuery query;
    
    query.prepare("SELECT * FROM VALUTA");
    
    query.exec();
    
    ui->tableWidget->setColumnCount(3);
    ui->tableWidget->setRowCount(8);
    ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "იდ" << "სახელი" << "კურსი");
    ui->tableWidget->verticalHeader()->hide();
    
    int i = 0;
    
    while(query.next()){
        int j = 0;
        while(j < 3){
            QTableWidgetItem* itm = new QTableWidgetItem(query.value(j).toString());
            ui->tableWidget->setItem(i,j,itm);
    
            if(j == 0){
                itm->setFlags(itm->flags() ^ Qt::ItemIsEditable); // **DISABLE EDIT**
            }
    
            j++;
        }
        i++;
    }
    

    But the concrete problem has not been reached.
    I write as resolved?


  • Qt Champions 2016

    @Taz742
    If you still have the view issue then leave it open :)



  • @mrjj
    Yes, I will leave open. I think This topical theme.



  • Hi,

    Did you forget to emit dataChanged() signal after value updated?
    This signal is must if you need to reflect the changes on UI.



  • Hi. @RajeeshRaveendran
    YES, I've seen this signal.
    But UI->, update, when it changes, model-> setData doing nothing.


  • Qt Champions 2016

    @Taz742
    Did u try to call
    emit dataChanged()
    in setData ?



  • Hi Taz,

    I did not get you. Let me explain a little more. Simply you should modify your model class to

    bool EditAbleModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
    {
    /// update the data to database/internal data storage
    emit dataChanged(); /// So that UI (QML) know the change occurred in background and query the new value by calling data() method to update UI.
    }

    QVariant EditAbleModel::data(const QModelIndex &index, int role)
    {
    /// return your data as per custom db.
    }



  • @RajeeshRaveendran
    Now I'm busy with something else and definitely I'll see into your answer.
    thank for reply, and sorry english :))


Log in to reply
 

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