3

I am a beginner in C++. And I don't understand this error. I just need you to explain me.

I try to show a .sqlite database in a QTableview. The problem come from:

model->setQuery(*qry);

I want to use a function called setQuery but in first argument, I set an object with *QSqlQuery type. And this error show up.

ERROR Pics

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QSqlQuery>
#include <QSqlQueryModel>
#include <QSqlDatabase>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QSqlDatabase DB;
    QSqlQueryModel* model;

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;

    DB = QSqlDatabase::addDatabase("QSQLITE");
    DB.setDatabaseName("Prices.sqlite");

    if (DB.open()) {
        qDebug() << "Open";

        model = new QSqlQueryModel();

        QSqlQuery* qry = new QSqlQuery(DB);
        qry->prepare("SELECT * FROM Prices");
        qry->exec();

        model->setQuery(*qry);
        ui->tableView->setModel(model);

        qDebug() << "Rows: " << model->rowCount();

        DB.close();
    }
    else {
        qDebug() << "Failed connection";
    }
}


marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
thacaout
  • 33
  • 4
  • 1st off: That's a warning message, not an error. – πάντα ῥεῖ Nov 29 '21 at 18:57
  • 2nd: the QSqlQuery is leaking. Create it on the stack and then pass it to setQuery() via std::move() – chehrlic Nov 29 '21 at 19:23
  • The only thing that should be done in a destructor is freeing resources. Qt has an elaborate (I know: also complicated) message system that can catch things closing, etc. Check out Signals and Slots. Also: https://stackoverflow.com/questions/130117/if-you-shouldnt-throw-exceptions-in-a-destructor-how-do-you-handle-errors-in-i – Nathaniel Johnson Apr 26 '22 at 16:01

1 Answers1

2

They want you to move the object behind qry into the function.

The shortest change would be to replace

model->setQuery(*qry);

with

model->setQuery(std::move(*qry));
delete qry;

You don't need to use new/delete in this case though. Just using automatic storage duration works:

    QSqlQuery qry(DB);
    qry.prepare("SELECT * FROM Prices");
    qry.exec();
    model->setQuery(std::move(qry));

Then you don't have to worry about forgetting to delete it.

Alternatively, since the QSqlQuery object is not used anywhere else, it might be best to chose the other overload for setQuery like this:

model = new QSqlQueryModel();
model->setQuery("SELECT * FROM Prices", DB);
ui->tableView->setModel(model);
PeterT
  • 7,981
  • 1
  • 26
  • 34
  • This is technically the answer to the OPs question, but I would also wrap up @Alexey answer and include a smart pointer answer. – Nathaniel Johnson Apr 26 '22 at 15:58
  • @Alexey this answer was written at the time of Qt 6.2, your answer works fine for Qt 6.0, 6.1, and then aftwards for Qt 6.3+ . My answer was very specifically for Qt 6.2 https://doc-snapshots.qt.io/qt6-6.2/qsqlquerymodel.html – PeterT Apr 26 '22 at 16:49
  • Nvm, I don't even know if Alexeys answer works for Qt 6.3 and upwards. Doesn't look like it to me. Since the deprecation of the const& version was not undone https://doc.qt.io/qt-6/qsqlquerymodel-obsolete.html – PeterT Apr 26 '22 at 16:59
  • @PeterT My fault about using QSqlQueryModel setQuery. Yes, it is indeed awaits rvalue and QSqlQuery should be passed using std::move. But I want to mention that instantiating an QSqlQuery object in heap is a *bad* practice and should never be used. I'll delete my answer, as yours one covers it. – Alexey Apr 28 '22 at 12:32