The second time I try to connect to a database, I get this message:
QSqlDatabasePrivate::removeDatabase: connection 'CompanyDatabase' is still in use, all queries will cease to work.
I delete the Model that I had previously used, I delete all connections, and I close the database. Below I have included the widget that opens the CompanyWidget as a modal dialog, because I think it might be relevant how I am opening/closing the widget which uses the database. Cany anyone explain why this database is still in use?
EDIT: If I change the QSqlDatabase member to a pointer and create it using:
this->CompanyDatabase = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", "CompanyDatabase"));
and delete it before re-adding the database:
if(this->CompanyDatabase)
{
delete this->CompanyDatabase;
this->CompanyDatabase = NULL;
}
then the error goes away. Why is this any different then the way I was doing it with the non-pointer member?
EditCompanyWidget.h
#ifndef EditCompanyWidget_H
#define EditCompanyWidget_H
#include "ui_EditCompanyWidget.h"
#include <QDialog>
#include <QSqlDatabase>
class QSqlTableModel;
class EditCompanyWidget : public QDialog, private Ui::EditCompanyWidget
{
Q_OBJECT
public:
EditCompanyWidget(QSqlDatabase);
~EditCompanyWidget();
public slots:
void on_btnExit_clicked();
protected:
QSqlTableModel* Model;
};
#endif
EditCompanyWidget.cpp
#include "EditCompanyWidget.h"
#include <iostream>
#include <QSqlDatabase>
#include <QStringList>
#include <QSqlQuery>
#include <QDebug>
#include <QSqlError>
#include <QVariant>
#include <QSqlTableModel>
#include <QSqlRecord>
EditCompanyWidget::EditCompanyWidget(QSqlDatabase database) : QDialog(NULL)
{
setupUi(this);
//QSqlTableModel* model = new QSqlTableModel;
this->Model = new QSqlTableModel(NULL, database);
this->Model->setTable("CompanyTable");
this->Model->setEditStrategy(QSqlTableModel::OnManualSubmit);
//model->setFilter(QString("id=%1").arg(1));
this->Model->select();
this->tableView->setModel(this->Model);
}
EditCompanyWidget::~EditCompanyWidget()
{
if(this->Model)
{
std::cout << "destructor Deleting..." << std::endl;
delete this->Model;
this->Model = NULL;
}
}
void EditCompanyWidget::on_btnExit_clicked()
{
this->Model->revertAll();
if(this->Model)
{
std::cout << "btnExit Deleting..." << std::endl;
delete this->Model;
this->Model = NULL;
}
//this->setResult(QDialog::Rejected);
this->reject();
}
MainWidget.h
#ifndef TimeTrackerConfigurationWidget_H
#define TimeTrackerConfigurationWidget_H
#include "ui_TimeTrackerConfigurationWidget.h"
#include <QMainWindow>
#include <QSqlDatabase>
class TimeTrackerConfigurationWidget : public QMainWindow, private Ui::TimeTrackerConfigurationWidget
{
Q_OBJECT
public:
TimeTrackerConfigurationWidget(QWidget *parent = 0);
public slots:
void on_btnNewCompany_clicked();
void on_btnEditCompany_clicked();
protected:
QSqlDatabase CompanyDatabase;
};
#endif
MainWidget.cpp
#include "TimeTrackerConfigurationWidget.h"
#include "EditCompanyWidget.h"
#include <iostream>
#include <QSqlDatabase>
#include <QFileDialog>
#include <QSqlError>
#include <QSqlQuery>
TimeTrackerConfigurationWidget::TimeTrackerConfigurationWidget(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
}
void TimeTrackerConfigurationWidget::on_btnEditCompany_clicked()
{
// QString fileName = QFileDialog::getOpenFileName(this, "Database File", ".", "Image Files (*.sqlite)");
//
// if(fileName.toStdString().empty())
// {
// std::cout << "Filename was empty." << std::endl;
// return;
// }
QString fileName = "test.sqlite";
if(!QFile::exists(fileName))
{
std::cerr << "File does not exist!" << std::endl;
return;
}
this->CompanyDatabase.close();
//QSqlDatabase::removeDatabase("CompanyDatabase");
//QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
// Delete all connections
for(unsigned int i = 0; i < QSqlDatabase::connectionNames().size(); ++i)
{
//QSqlDatabase::removeDatabase("TestConnection");
QSqlDatabase::removeDatabase(QSqlDatabase::connectionNames()[i]);
}
this->CompanyDatabase = QSqlDatabase::addDatabase("QSQLITE", "CompanyDatabase");
//this->CompanyDatabase = QSqlDatabase::addDatabase("QSQLITE");
this->CompanyDatabase.setDatabaseName(fileName);
if (!this->CompanyDatabase.open())
{
std::cerr << "Could not open database" << std::endl;
std::cerr << this->CompanyDatabase.lastError().text().toStdString() << std::endl;
return;
}
EditCompanyWidget* editCompanyWidget = new EditCompanyWidget(this->CompanyDatabase);
editCompanyWidget->exec();
delete editCompanyWidget;
}
The documentation says it clearly: http://doc.qt.io/qt-4.8/qsqldatabase.html#removeDatabase. You have to destroy all the queries objects and the QSqlDatabase connection objects you have instantiated before removing the connection. When you delete the pointer, you're actually doing this. With your previous code, you weren't.