gpt4 book ai didi

c++ - Qt在不在主类中的函数中执行SQL命令

转载 作者:太空宇宙 更新时间:2023-11-04 12:55:02 25 4
gpt4 key购买 nike

所以,我有一个关于 QT 和 SQL 命令的问题,我已经坐了好几个小时了,但它很可能会很简单。

我试图拥有多种形式,在每一种形式中我都连接数据库,并执行一些操作。这工作正常,但是 - 一旦我将所述操作移动到 button_pressed 函数,我就会收到数据库未打开错误。我没有在这个类的任何地方关闭数据库,但错误仍然存​​在。

我现在看到问题的一部分是以下错误:

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.

当我重组代码(用于调试)并删除第一种形式的连接时,错误消失了,数据库在第二类函数中保持打开状态。下面,二级类

HomeScreen::HomeScreen(QWidget *parent):QWidget(parent),ui(newUi::HomeScreen){
ui->setupUi(this);
connect(ui->btnInclogShow,SIGNAL(pressed()),this,SLOT(ShowLogs()));
dbe = QSqlDatabase::addDatabase("QMYSQL");
dbe.setDatabaseName("securitydb");
dbe.setUserName("root");
dbe.setPassword("");
dbe.open();
if(dbe.open()){
qDebug() << "Database is open in main part";
}
else{qDebug() << "Database is closed";}
}

HomeScreen::~HomeScreen()
{
delete ui;
}

void HomeScreen::ShowLogs()
{
qDebug() << "Showlogs pressed";
if(dbe.open()){
qDebug() << "Database is open";
}
else{qDebug() << "Database is closed";}
}

初级类(class)以下

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

ui->setupUi(this);

db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("securitydb");
db.setUserName("root");
db.setPassword("");
db.open();

connect(ui->btnLogin,SIGNAL(pressed()),this,SLOT(LoginClicked()));
if(db.open()){
qDebug() << "Database is open";
}
else{qDebug() << "Database is closed";}
}

MainWindow::~MainWindow()
{
delete ui;
db.close();
db.removeDatabase("securitydb");
}

void MainWindow::LoginClicked()
{
qDebug() << "pressed";
this->destroy();
HomeScreengui->show();
}

为了缓解这个问题,我在第二个类中声明了一个新的数据库变量,但这没有用。任何帮助将不胜感激!

最佳答案

首先,您必须了解QSqlDatabase 的工作原理。

Qt 管理一个数据库连接列表。每个连接都由一个唯一的名称标识。您可以添加新连接、检索现有连接或从列表中删除连接。这是使用函数完成的:

  • QSqlDatabase::addDatabase()
  • QSqlDatabase::database()
  • QSqlDatabase::removeDatabase()

QSqlDatabase 的多个实例也可以引用同一个连接。所以在下面的代码中 db0db1 指的是同一个连接。

QSqlDatabase db0 = QSqlDatabase::addDatabase("MYSQL", "foo");
QSqlDatabase db1 = QSqlDatabase::database("foo");

此外,在需要连接名称的函数中,您可以省略名称。 Qt 会将其作为默认 数据库处理。如果您只有一个连接,这会很方便。

请注意,Qt 使用“qt_sql_default_connection”作为默认数据库的名称。因此,例如 QSqlDatabase::database()QSqlDatabase::database("qt_sql_default_connection") 返回相同的连接。


现在查看您的代码。您在两个构造函数中调用 QSqlDatabase::addDatabase("QMYSQL");。第二次调用将在 Qt 管理的连接列表中添加一个新连接,并将删除您之前的连接。这就是为什么您会收到以下警告:

QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

此外,由于删除的连接正在使用中,您会收到额外的警告:

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

要解决这个问题,您只需调用一次QSqlDatabase::addDatabase()。这可以通过让其中一个类负责处理数据库连接来完成,其他类将只调用QSqlDatabase::database(),但是你必须确保你只有一个这个类的实例。或者您可以在每个类中调用 QSqlDatabase::addDatabase(),但前提是数据库尚不存在(参见 QSqlDatabase::contains() ):

// Add a default databse only if it does not exist.
if (!QSqlDatabase::contains())
{
QSqlDatabase::addDatabase("MYSQL");
}

您的行 db.removeDatabase("securitydb"); 也是完全错误的。 QSqlDatabase::removeDatabase() 是一个静态函数,参数是连接名,不是数据库名。应该是:

QSqlDatabase::removeDatabase(); // Remove the default database

所以你的代码应该是这样的:

HomeScreen::HomeScreen(QWidget *parent):QWidget(parent),ui(newUi::HomeScreen)
{
ui->setupUi(this);
connect(ui->btnInclogShow, &QPushButton::pressed, this, &HomeScreen::ShowLogs);

if (QSqlDatabase::contains())
dbe = QSqlDatabase::addDatabase("QMYSQL");
else
dbe = QSqlDatabase::database();

dbe.setDatabaseName("securitydb");
dbe.setUserName("root");
dbe.setPassword("");

if(dbe.open()){
qDebug() << "Database is open in main part";
}
else{
qDebug() << dbe.lastError().text();
}
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

ui->setupUi(this);

if (QSqlDatabase::contains())
db = QSqlDatabase::addDatabase("QMYSQL");
else
db = QSqlDatabase::database();

db.setDatabaseName("securitydb");
db.setUserName("root");
db.setPassword("");

connect(ui->btnLogin, &QPushButton::pressed,this, &MainWindow::LoginClicked);
if(db.open()){
qDebug() << "Database is open";
}
else{
qDebug() << dbe.lastError().text();
}
}

MainWindow::~MainWindow()
{
delete ui;
// WARNING: If HomeScreen is still using the connection the next 2 lines will leak resources and make HomeScreen lose its connection.
db.close();
QSqlDatabase::removeDatabase();
}

关于c++ - Qt在不在主类中的函数中执行SQL命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46993972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com