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

Strange selectionModel()->selectedRows() problem.



  • Hi,

    Can someone give me a heads up on why the following code would stop working after adding data to a SQL database?

     QModelIndexList selectedRows = ui->equipmentTableWidget->selectionModel()->selectedRows();
    

    This function is inside a slot that is called when the selections are changed. It returns the proper values until I add information to the table and update a SQL database. After that selectedRows.count() is always 0 until I exit the program and start over again. At this point it works fine but if I add another item to the table and database it starts returning 0 again.

    Using windows 7 with QT 5.9.1 and minGW compiler.

    Thanks


  • Lifetime Qt Champion

    Hi,

    Can you show the code you wrote that interacts with the model and database ?



  • Hi,

    Here is the code that calls the dialog and adds to the database.

    void MainWindow::processNewEquipment()
    {
        equipmentDialog dialog;
    
        if(dialog.exec() == dialog.Accepted) {
            QSqlQuery sql;
            sql.prepare(EQUIPMENT_TABLE_INSERT);
            sql.bindValue(":equipmentID", dialog.getEquipmentID());
            sql.bindValue(":equipmentDescription", dialog.getEquipmentDescription());
            sql.bindValue(":equipmentIDNumber", dialog.getEquipmentIDNumber());
            sql.bindValue(":equipmentPurchaseMileage", dialog.getEquipmentPurchaseMileage());
            sql.bindValue(":equipmentCurrentMileage", dialog.getEquipmentCurrentMileage());
            sql.bindValue(":equipmentCurrentOperator", dialog.getEquipmentCurrentOperator());
            sql.bindValue(":equipmentPurchasePrice", dialog.getEquipmentPurchasePrice());
            sql.bindValue(":equipmentExpenses", dialog.getEquipmentExpenses());
            sql.bindValue(":equipmentIncomeGenerated", dialog.getEquipmentIncomeGenerated());
            sql.bindValue(":equipmentLicenseNumber", dialog.getEquipmentLicenseNumber());
            sql.bindValue(":equipmentNotes", dialog.getEquipmentNotes());
            if(sql.exec()) {
                QMessageBox::information(this, "processNewEquipment", tr("New Equipment added to the database!"));
                loadEquipmentDatabase();
            }
            else QMessageBox::critical(this, tr("Error:: "), sql.lastError().text());
        }
    }
    

    And this is the code that loads the table.

    void MainWindow::loadEquipmentDatabase()
    {
        QSqlQueryModel * model = new QSqlQueryModel();
        QSqlQuery * sql = new QSqlQuery();
    
        sql->prepare(EQUIPMENT_TABLE_READ_ALL);
        if(sql->exec()) {
            model->setQuery(*sql);
            ui->equipmentTableWidget->setModel(model);
        }
        else QMessageBox::critical(this, tr("Error::"), sql->lastError().text());
    }
    

    Thnks



  • After further testing, it has something to do with the second call to loadEquipmentDatbase(); if I comment out that line it still works fine just the table is not updated.


  • Lifetime Qt Champion

    Each time you call loadEquipmentDatabase you create a new model, why ? Just replace the query. By the way why are you allocating the QSqlQuery object on the heap ?
    By the way, why not call model->setQuery(EQUIPMENT_TABLE_READ_ALL) ?



  • When I did research on filling a QTableWidget from SQL that is what I come up with. Can you provide an example on how to do this correctly?



  • just

    • move QSqlQueryModel * model = new QSqlQueryModel(); and ui->equipmentTableWidget->setModel(model); in the constructor
    • change model->setQuery(*sql); to ui->equipmentTableWidget->model()->setQuery(sql);
    • change QSqlQuery * sql = new QSqlQuery(); to QSqlQuery sql;


  • Hi and thanks for the info, however ui->equipmentTableWidget->model()->setQuery(sql); generates the following error.

    error: 'class QAbstractItemModel' has no member named 'setQuery'
         ui->equipmentTableWidget->model()->setQuery(EQUIPMENT_TABLE_READ_ALL);
                                            ^
    

    So what I did was per your advice moved the suggested code to the constructor. then in my loadEquipmentDatabase() function I placed

    QSqlQueryModel *model = qobject_cast<QSqlQueryModel*>(ui->equipmentTableWidget->model());
        if(model)
            model->setQuery(EQUIPMENT_TABLE_READ_ALL);
    

    Not sure if that is the proper way but it works as expected now.

    Thanks.


Log in to reply