C++ QSqlDatabase:如何避免仍在使用的“qt\u sql\u默认\u连接”和重复连接相关警告?

C++ QSqlDatabase:如何避免仍在使用的“qt\u sql\u默认\u连接”和重复连接相关警告?,c++,qt,sqlite,qt5,qtableview,C++,Qt,Sqlite,Qt5,Qtableview,如果这是一个微不足道的问题,很抱歉,但我一直在尝试构建一个小的.ui,它使用QSQLITE作为数据库,并使用QTableView在默认数据库文件上显示4列作为示例 我从各个方面调试了问题,更改了SQL的逻辑操作,并以更简单的方式重新构造了构造函数,但错误仍然存在 设置完所有参数后,我发现以下错误: QSqlDatabasePrivate::removeDatabase:连接“qt\u sql\u default\u connection”仍在使用中,所有查询将停止工作 及 QSqlDatabas

如果这是一个微不足道的问题,很抱歉,但我一直在尝试构建一个小的.ui,它使用QSQLITE作为数据库,并使用QTableView在默认数据库文件上显示4列作为示例

我从各个方面调试了问题,更改了SQL的逻辑操作,并以更简单的方式重新构造了构造函数,但错误仍然存在

设置完所有参数后,我发现以下错误:

QSqlDatabasePrivate::removeDatabase:连接“qt\u sql\u default\u connection”仍在使用中,所有查询将停止工作

QSqlDatabasePrivate::addDatabase:重复的连接名称“qt\u sql\u default\u connection”,已删除旧连接

我查看了几个描述这个错误的来源,比如,这个。也很有用,但还是什么都没发生。官方文件显示了这样做的错误和正确的方式。但错误依然存在。在所有这些不同的选择之后,我以一种更简洁的方式重新编写了代码,我希望有人能够阐明这个问题

在代码截取部分下方:

主窗口

mainwindow.cpp

datainfo.h

请阐明可能的解决方案。

简短回答 您应该指定要在其上运行的数据库,否则它们将在默认数据库上运行。您可以在QSqlQuery的构造函数中使用

QSqlQuery QUERYQSQLDABASE::databasemy db

您将QSqlDatabase的副本保留为dataInfo类的成员,这将阻止它正确关闭。相反,只需在需要时使用静态QSqlDatabase::databasename即可

auto db=QSqlDatabase::databasemy db

细节 为QSqlQuery提供正确的数据库

更改QSqlQuery的所有用途。例如,对于confDataBase:

不保留QSqlDatabase属性

从文件中:

警告:强烈建议您不要将QSqlDatabase的副本作为类的成员保留,因为这将阻止在关闭时正确清理实例。如果您需要访问现有的QSqlDatabase,则应使用database访问它。如果选择使用QSQLDABASE成员变量,则需要在删除QCoreApplication实例之前删除该变量,否则可能导致未定义的行为

将数据库的名称存储在类中,并将getDatabase更改为

dataInfo.cpp

生成警告的Qt代码

要查看产生错误的实际代码,请执行以下操作:


invalidateDb在添加或删除连接时使用,如果引用计数>1,将触发错误。当您抓住一个时,这将触发错误。

@Adrien Leravat,感谢您花时间阅读此问题。我按照您的建议更改了getDatabase函数,但它仍然不起作用。我认为您还提到了修改initDataBaseconst QString&nameDB函数,该函数包含以下语句mDBImages=QSqlDatabase::addDatabaseQSQLITE;但是该如何修改这个函数呢。我不认为更改mDBImages=QSqlDatabase::addDatabaseQSQLITE;如果有帮助的话,只需使用本地实例就可以了。你能试着直接在addDatabase中传递数据库名吗。。。调用,作为第二个参数?您在其他地方有其他QSQL数据库吗?我记得有这个问题,我必须手动关闭每个数据库,并确保没有查询处于活动状态,但我对警告中的默认名称感到非常奇怪。此外,如果您不将数据库提供给QSqlTableModel,问题会消失吗?如果您完全推荐您的QSqlTableModel代码?你是否摆脱了qsqlmdbimages数据库;在标题中也是这样吗?这么多问题:没问题:我感谢你花时间帮忙!我正在尝试你的建议。给我几分钟时间核实一下。非常感谢你抽出时间阿德里安·勒拉瓦特!
private:
    QString temporaryFolder;
    dataInfo *mNewDatabaseImages;
    QSqlTableModel *mNewTableImages;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    temporaryFolder = "/home/to/Desktop/tempDBFolder/tmp.db";
    QFile dbRem(temporaryFolder);
    dbRem.remove();
    mNewDatabaseImages = new dataInfo(this);
    mNewDatabaseImages->initDataBase(temporaryFolder);
    mNewDatabaseImages->confDataBase();
    mNewTableImages = new QSqlTableModel(this, mNewDatabaseImages->getDatabase());
    mNewTableImages->setTable("leftCamTable");
    mNewTableImages->select();
    ui->bookMarkTableView->setModel(mNewTableImages);
    ui->bookMarkTableView->showColumn(true);
}
#ifndef DATAINFO_H
#define DATAINFO_H
#include <QObject>
#include <QSqlDatabase>
#include "imageparam.h"

class dataInfo : public QObject
{
    Q_OBJECT
public:
    explicit dataInfo(QObject *parent = nullptr);
    bool initDataBase(const QString &nameDB);
    bool confDataBase();
    bool addItem(ImageParam* imageItem);
    QSqlDatabase getDatabase();
private:
    QString mError;
    QSqlDatabase mDBImages;
};
#endif // DATAINFO_H
#include "datainfo.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QVariant>
#include <QMessageBox>

#define CREATE_TABLE \
    " CREATE TABLE IF NOT EXISTS imageTable" \
    " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL" \
    " path1 TEXT NOT NULL" \
    " path2 TEXT NOT NULL" \
    " imageA BLOB NOT NULL" \
    " imageB BLOB NOT NULL)"

dataInfo::dataInfo(QObject *parent) : QObject(parent)
{}

bool dataInfo::initDataBase(const QString &nameDB)
{
    mDBImages = QSqlDatabase::addDatabase("QSQLITE");
    mDBImages.setDatabaseName(nameDB);
    bool ok = mDBImages.open();
    if(!ok) {
        mError = mDBImages.lastError().text();
        qDebug() << mError;
    }
    return ok;
}

bool dataInfo::confDataBase()
{
    QSqlQuery qry;
    bool ok = qry.exec(CREATE_TABLE);
    if(!ok) {
        mError = qry.lastError().text();
    }
    return ok;
}

bool dataInfo::addItem(ImageParam *imageItem)
{
    QSqlQuery qry;
    qry.prepare("INSERT INTO imageTable (path1, path2, imageA, imageB)" \
                " VALUES (?,?,?,?)");
    qry.addBindValue(imageItem->path1());
    qry.addBindValue(imageItem->path2());
    qry.addBindValue(imageItem->image1());
    qry.addBindValue(imageItem->image2());
    bool ok = qry.exec();
    if(!ok) {
        mError = qry.lastError().text();
    }
    return ok;
}

QSqlDatabase dataInfo::getDatabase()
{
    return mDBImages;
}
db->setDatabaseName("name");
if(!db->open()) {
    qDebug() << "Error opening ";
    return false;
}
bool dataInfo::confDataBase()
{
    // Explicitly provide your database to the query
    // Otherwise the default database is used
    QSqlQuery qry(getDatabase());
    bool ok = qry.exec(CREATE_TABLE);
    if(!ok) {
        mError = qry.lastError().text();
    }
    return ok;
}
bool dataInfo::initDataBase(const QString &nameDB)
{
    // Save database's name
    mDBName = nameDB;
    // Use the database locally, without storing it
    auto dbImages = QSqlDatabase::addDatabase("QSQLITE", nameDB);
    bool ok = dbImages.open();
    if(!ok) {
        mError = dbImages.lastError().text();
        qDebug() << mError;
    }
    return ok;
}

QSqlDatabase dataInfo::getDatabase()
{
    return QSqlDatabase::database(mDBName);
}
private:
    QString mError;
    QString mDBName;