c++ - QSqlDatabase:如何避免“qt_sql_default_connection”仍在使用和重复连接相关警告?
问题描述
抱歉,如果这是一个微不足道的问题,但我一直在尝试构建一个小的 .ui 用作QSQLITE
数据库,并用于QTableView
在默认数据库文件上显示 4 列作为示例。
我在各个方面都调试了问题,更改了逻辑操作SQL
并以更简单的方式重组了构造函数,但错误仍然存在。
完成设置所有参数后,我收到此错误:
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
和
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
我查看了描述此错误的几个来源,例如此来源、此其他来源。这也很有用,但仍然没有任何反应。官方文档在这里提出了一种“错误”和“正确”的方法。但错误仍然存在。在所有这些不同的选项之后,我以更简洁的方式恢复了代码,我希望有人可以阐明这个问题。
下面的代码片段:
主窗口.h
private:
QString temporaryFolder;
dataInfo *mNewDatabaseImages;
QSqlTableModel *mNewTableImages;
主窗口.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);
}
数据信息.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
数据信息.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;
}
我还查看了这篇建议首先为数据库设置名称的帖子,但我已经在函数中这样做了initDataBase(const QString &nameDB)
。这是建议该程序的帖子,如下所示:
db->setDatabaseName("name");
if(!db->open()) {
qDebug() << "Error opening ";
return false;
}
请阐明可能的解决方案。
解决方案
简短的回答
您应该指定要在其上运行的数据库
QSqlQuery
,否则它们将在默认数据库上运行。QSqlQuery
您可以在的构造函数中指定数据库QSqlQuery query(QSqlDatabase::database("my-db"));
您
QSqlDatabase
作为班级成员保留了 的副本dataInfo
,这将阻止它正确关闭。相反,只需QSqlDatabase::database("name")
在需要时使用静态。auto 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 属性
从文档中:
警告:强烈建议您不要将 QSqlDatabase 的副本作为类的成员保留,因为这将阻止实例在关闭时被正确清理。如果您需要访问现有的 QSqlDatabase,则应使用 database() 访问它。如果你选择有一个 QSqlDatabase 成员变量,则需要在删除 QCoreApplication 实例之前将其删除,否则可能会导致未定义的行为。
将您的数据库名称存储在您的类中,并将您的更改getDatabase
为
数据信息.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);
}
数据信息.h
private:
QString mError;
QString mDBName;
Qt 的代码生成警告
查看产生错误的实际代码:https ://code.woboq.org/qt5/qtbase/src/sql/kernel/qsqldatabase.cpp.html#170
invalidateDb
在添加或删除连接时使用,如果引用计数> 1,将触发错误。当您持有一个时,这将触发错误。
推荐阅读
- python - Django 2.1.3/SQLite:唯一约束失败:users_profile.user_id || 尝试访问我的超级用户帐户时
- python - AttributeError:'list'对象没有属性'split'-使用croniter打印下一个crontab计划作业-stdout-Python
- ruby - 是否可以在 ruby 的类中调用覆盖的 to_s?
- matlab - 如何绘制离散(z 域)传递函数的斜坡响应?[MATLAB]
- matlab - 如何绘制带有约束的曲面图
- c# - 以定义的顺序调用多个方法
- laravel - 使用 Laravel Eloquent 检索所有父值
- react-native - React Navigation:切换到不同的堆栈并能够返回到上一个堆栈
- c - gsl_vector_get() 在 printf() 中返回错误值
- java - 错误:链接有关字符串资源的文件资源失败