You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QSqlQuery拷贝警告问题:如何改用移动构造传递参数?

Qt SQLite操作中QSqlQuery传递警告的解决方法

在Qt中基于SQLite编写数据保存与编辑代码时,传递QSqlQuery对象会触发警告:QSqlQuery is deprecated: is not mean to be copied: use move construction instead,下面结合你的代码给出正确实现方式。

问题原因

QSqlQuery的拷贝构造函数已被标记为废弃,因为它内部持有数据库连接、查询状态等资源,直接拷贝会导致资源管理冲突,Qt官方推荐使用移动语义或者避免传递QSqlQuery实例,改为在需要的地方创建独立的QSqlQuery对象。

推荐解决方案:避免传递QSqlQuery,函数内部创建实例

这种方式更安全,每个数据库操作使用独立的QSqlQuery,避免多个操作共享同一实例导致的状态混乱,同时彻底消除警告。

步骤1:修改相关函数,移除QSqlQuery参数

将imprimirArticulos、registrarArticulo、filtroArticulos、imprimirCategorias、agregarCategorias这些函数的参数中的QSqlQuery去掉,改为在函数内部基于类成员的db对象创建新的QSqlQuery:

示例(以imprimirArticulos为例):

int MainWindow::imprimirArticulos()
{
    QSqlQuery query(db); // 使用类中已打开的db对象创建新query
    // 执行你的查询、数据处理逻辑
    // ...
    return 0; // 返回你的id值
}

步骤2:修改构造函数中的调用与连接

去掉所有传递QSqlQuery的代码,直接调用无参函数,信号连接也改为直接绑定成员函数:

修改后的完整构造函数代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{   
    ui->setupUi(this);
    char dirNow[1024];

    db = QSqlDatabase::addDatabase("QSQLITE");
    QString dirfull = QString(_getcwd(dirNow, 1024)) + "\\inventario.db";
    db.setDatabaseName(dirfull);

    if(!db.open()){
        qDebug() << db.lastError().text();
    }

    model = new QSqlQueryModel();

    // 临时query用于建表操作
    QSqlQuery query(db);

    if(!query.exec("CREATE TABLE IF NOT EXISTS articulo (codigo INTEGER NOT NULL, nombre VARCHAR(55) NOT NULL, unidades INTEGER NOT NULL, "
                   "categoria VARCHAR(55) NOT NULL, pais VARCHAR(55) NOT NULL, precio DOUBLE NOT NULL, foto VARCHAR(200) NOT NULL, id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT) ")){
            QMessageBox::information(this, "Error", query.lastError().text());
    }

    if(!query.exec("CREATE TABLE IF NOT EXISTS categorias(valor VARCHAR(55) NOT NULL) ")){
        QMessageBox::information(this, "Error", query.lastError().text());
    }

    // 直接调用无参函数
    id = imprimirArticulos();

    // 信号连接直接绑定成员函数
    QObject::connect(ui->registrarBtn, &QPushButton::clicked, this, &MainWindow::registrarArticulo);
    QObject::connect(ui->addImagenBtn, &QPushButton::clicked, this, &MainWindow::subirFoto);
    QObject::connect(ui->buscarBtn, &QPushButton::clicked, this, &MainWindow::filtroArticulos);

    imprimirCategorias();
    QObject::connect(ui->categoriasCBox, &QComboBox::currentIndexChanged, this, &MainWindow::agregarCategorias);

    // 为QSqlQueryModel创建独立的query
    QSqlQuery modelQuery(db);
    modelQuery.exec("SELECT * FROM articulo"); // 替换为你需要的查询语句
    model->setQuery(std::move(modelQuery));
}

备选方案:使用移动语义传递QSqlQuery(仅适合单次传递场景)

如果你确实需要传递QSqlQuery,可以使用std::move转移对象所有权,但要注意:一旦调用std::move,原QSqlQuery对象会处于无效状态,不能再被后续代码使用。

示例:

// 仅单次传递时使用
id = imprimirArticulos(std::move(query));
// 注意:此时原query对象已失效,不能再用于后续的imprimirCategorias等操作

显然这种方式不适合你当前的场景,因为你需要多次使用query对象,所以推荐第一种方案。

内容的提问来源于stack exchange,提问作者Juan Diego Monroy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:20:39