C++ Qt在主类以外的函数中执行SQL命令

C++ Qt在主类以外的函数中执行SQL命令,c++,mysql,sql,qt,C++,Mysql,Sql,Qt,所以,我有一个关于QT和SQL命令的问题,我已经和它坐了几个小时了,但很可能它会很简单 我试图创建多个表单,在每个表单中连接数据库并执行一些操作。然而,这工作正常-只要我移动所述操作以表示按钮按下功能,我就会收到数据库未打开错误。我没有关闭该类中任何位置的数据库,但错误仍然存在 我现在看到问题的一部分是以下错误: QSqlDatabasePrivate::removeDatabase:连接“qt\u sql\u default\u connection”仍在使用中,所有查询将停止工作 QSqlD

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

我试图创建多个表单,在每个表单中连接数据库并执行一些操作。然而,这工作正常-只要我移动所述操作以表示按钮按下功能,我就会收到数据库未打开错误。我没有关闭该类中任何位置的数据库,但错误仍然存在

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

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

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

当我重新构造代码(用于调试)并删除第一个表单中的连接时,错误就会消失,数据库在第二个类函数中保持打开状态。 下面是中学班

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";}
}
HomeScreen::HomeScreen(QWidget*父项):QWidget(父项),ui(newUi::HomeScreen){
用户界面->设置用户界面(此);
连接(ui->btnInclogShow,信号(按下()),此,插槽(ShowLogs());
dbe=QSqlDatabase::addDatabase(“QMYSQL”);
dbe.setDatabaseName(“securitydb”);
dbe.setUserName(“根”);
dbe.setPassword(“”);
dbe.open();
if(dbe.open()){

qDebug()每次在同一基础数据库上调用
addDatabase
,请确保设置唯一的连接名称:

if (QSqlDatabase::contains("foo")) {
    QSqlDatabase::removeDatabase("foo");
}
db = QSqlDatabase::addDatabase("QMYSQL", "foo");
db.setDatabaseName("securitydb");
请注意,连接名称与数据库名称不同。因此,在这里您要打开多个到同一数据库的独立连接


如果未显式设置连接名,Qt将使用默认连接名。此默认连接名将用于对基础数据库的所有访问。因此,如果调用
close()
在使用默认连接名称打开的数据库上,它将有效地关闭使用该默认名称打开的所有数据库对象。

每次在同一基础数据库上调用
addDatabase
,请确保设置了唯一的连接名称:

if (QSqlDatabase::contains("foo")) {
    QSqlDatabase::removeDatabase("foo");
}
db = QSqlDatabase::addDatabase("QMYSQL", "foo");
db.setDatabaseName("securitydb");
请注意,连接名称与数据库名称不同。因此,在这里您要打开多个到同一数据库的独立连接


如果未显式设置连接名,Qt将使用默认连接名。此默认连接名将用于对基础数据库的所有访问。因此,如果调用
close()
在使用默认连接名称打开的数据库上,它将有效地关闭使用该默认名称打开的所有数据库对象。

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

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

  • QSqlDatabase::addDatabase()
  • QSqlDatabase::database()
  • QSqlDatabase::removeDatabase()
另外,
QSqlDatabase
的几个实例也可以引用同一个连接。因此,在下面的代码
db0
db1
中,引用同一个连接

QSqlDatabase db0 = QSqlDatabase::addDatabase("MYSQL", "foo");
QSqlDatabase db1 = QSqlDatabase::database("foo");
此外,在需要连接名称的函数中,可以省略该名称。Qt将作为默认数据库处理该名称。如果只有一个连接,这将非常方便

QSqlDatabase db0 = QSqlDatabase::addDatabase("MYSQL", "foo");
QSqlDatabase db1 = QSqlDatabase::database("foo");
请注意,Qt使用“”作为默认数据库的名称。因此,例如
QSqlDatabase::database()
QSqlDatabase::database(“Qt\u sql\u default\u连接”)
返回相同的连接

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

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

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

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

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

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

另外,您的行
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();
}
HomeScreen::HomeScreen(QWidget*父项):QWidget(父项),ui(newUi::HomeScreen)
{
用户界面->设置用户界面(此);
连接(ui->btnInclogShow,&QPushButton::pressed,this,&HomeScreen::ShowLogs);
if(QSqlDatabase::contains())
dbe=QSqlDatabase::addDatabase(“QMYSQL”);
其他的
dbe=QSqlDatabase::database();
dbe.setDatabaseName(“securitydb”);
dbe.setUserName(“根”);
dbe.setPassword(“”);
if(dbe.open()){
qDebug()btnLogin,&QPushButton::按下,此,&MainWindow::LoginClicked);
if(db.open()){

qDebug()首先,您必须了解
QSqlDatabase
的工作原理

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

  • QSqlDatabase::addDatabase()
  • <