数据库
首页 > 数据库> > c-QSqlDatabase:如何避免’qt_sql_default_connection’仍在使用和与重复连接有关的警告?

c-QSqlDatabase:如何避免’qt_sql_default_connection’仍在使用和与重复连接有关的警告?

作者:互联网

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

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

完成设置所有参数后,出现此错误:

QSqlDatabasePrivate :: removeDatabase:连接’qt_sql_default_connection’仍在使用中,所有查询将停止工作.

QSqlDatabasePrivate :: addDatabase:重复的连接名称’qt_sql_default_connection’,旧的连接已删除.

我查看了描述此错误的多个来源,例如this sourceother source.this也很有用,但仍然没有任何反应.官方文档建议使用“错误”和“正确”的方式来执行该操作here.但是错误仍然存​​在.在完成所有这些不同的选择之后,我以更简洁的方式重新编写了代码,并希望有人可以阐明这个问题.

下面的代码片段:

mainwindow.h

private:
    QString temporaryFolder;
    dataInfo *mNewDatabaseImages;
    QSqlTableModel *mNewTableImages;

mainwindow.cpp

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);
}

datainfo.h

#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

datainfo.cpp

#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;
}

我还查看了this post,该建议建议首先为数据库设置名称,但是我已经在initDataBase(const QString& nameDB)函数中进行了设置.这是建议该步骤的post,如下所示:

db->setDatabaseName("name");
if(!db->open()) {
    qDebug() << "Error opening ";
    return false;
}

请阐明可能的解决方案.

解决方法:

简短答案

>您应指定要在其上运行QSqlQuery的数据库,否则它们将在默认数据库上运行.您可以使用以下命令在QSqlQuery的构造函数中指定数据库:

QSqlQuery查询(QSqlDatabase :: database(“ my-db”));
>您将保留QSqlDatabase的副本作为dataInfo类的成员,这将防止它阻止正确关闭.相反,仅在需要时使用静态QSqlDatabase :: database(“ name”).

自动db = QSqlDatabase :: database(“ my-db”);

细节

为QSqlQuery提供合适的数据库

更改您对QSqlQuery的所有使用.例如confDataBase:

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;
}

不保留QSqlDatabase属性

从文档中:

Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior.

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

dataInfo.cpp

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);
}

dataInfo.h

private:
    QString mError;
    QString mDBName;

Qt的代码生成警告

看一下产生错误的实际代码:https://code.woboq.org/qt5/qtbase/src/sql/kernel/qsqldatabase.cpp.html#170

当添加或删除连接时,将使用invalidateDb,如果引用计数大于或等于2,将触发错误. 1.当您按住一个时,将触发错误.

标签:qtableview,c,sqlite,qt,qt5
来源: https://codeday.me/bug/20191012/1903852.html