PDA

View Full Version : Qt databse connection not available in multi window app



starlays
13th September 2017, 07:19
Hello,

In my app I have 2 forms and I want them to share same database connection.
The first is a login window and it is the first one started when the application is lunched, after successful authentication the login window is hidden and I start the main app window.

I'm using the database connection on the main form, I'm initializing this connection in the constructor like so:


login::login(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::login)
{
QString DB_FILE = QCoreApplication::applicationDirPath() + "/database.db";

ui->setupUi(this);

DB = QSqlDatabase::addDatabase("QSQLITE");
DB.setDatabaseName(DB_FILE);
QFileInfo checkFile(DB_FILE);

if(checkFile.isFile())
{
if(DB.open())
{
ui->statusbar->showMessage("[+] Connected to database");
}
}
else
{
ui->statusbar->showMessage("[!] Can't find the database file");
}
}

and the other window is showed after a successful login on a button click action like so:



void login::on_pushButton_clicked()
{
...
if(query.last())
{
ui->statusbar->showMessage("[+] Login success");
this->hide(); //hide the login window
wtimelog->show(); //show the app window
}
else
{
ui->statusbar->showMessage("[!] Wrong username or password");
}
...
}


I wander how can I make the already opened connection to the database available for the wtimelog window. At the moment it does not recognize any resources for the database from the main window as this resources are declared in another scope.

Thank you.

ado130
13th September 2017, 15:25
I think you are doing it wrong. Why do you open Mainwindow from Login form? Open Login form from Mainwindow and then e.g get DB from Login or you can define DB in Mainwindow and put pointer into Login form.

d_stranz
13th September 2017, 17:17
Why do you open Mainwindow from Login form?

I can sort of see the logic in this. If the login is not successful, you don't want the user to be able to access any of the functionality of the main window. But I agree that it is better to keep the DB as a member of the MainWindow class (or another non-GUI class that manages DB access). You can pass a pointer to the DB instance (or to a QSqlQuery instance) to the Login window.

You can guarantee that the Login dialog is displayed immediately on startup by adding a zero time single-shot QTimer in the MainWindow constructor. Connect the timer's timeout() signal to a MainWindow slot that calls exec() on the login dialog. The single-shot will fire as soon as the MainWindow's showEvent() completes and display the login. If the login fails, you can then call close() on your MainWindow to shut down the app (or give the user another try to login).

ado130
13th September 2017, 21:56
I can sort of see the logic in this. If the login is not successful, you don't want the user to be able to access any of the functionality of the main window.
As you wrote, he can make a signal-slot with bool value and check if the login was successful. Or in Login define bool value and after mainWindow calls exec() wait for true in while loop, so the program will start only after successfully logged or close the app.

starlays
14th September 2017, 20:38
Thank you for the help, I will change the app.

Now it remains to find out how can I pass a pointer to the other window. Should it be done as an argument to the constructor?

d_stranz
15th September 2017, 00:57
Now it remains to find out how can I pass a pointer to the other window. Should it be done as an argument to the constructor?

That's one way. You could also simply pass it with a setter method: void Login:: setDBPointer( QSqlDatabase * pDB ) that you call after you create the Login instance but before you call exec(). You'll need to write this method, of course.

Lesiok
15th September 2017, 08:18
You do not need to pass a QSqlDatabase pointer. Read about QSqlDatabase::database.

d_stranz
15th September 2017, 16:51
Yes, Lesiok is absolutely correct- I had forgotten about this. So, add and open the database in MainWIndow, then simply call QSqlDatabase:: database() from inside Login to get the reference to that database. No need to pass anything to Login.

starlays
17th September 2017, 12:53
Thank you guys, problem solved, changed the way windows are displayed and passed the database connection as a parameter and now it is working.