Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using Database in several MainWindows / classes



  • I am working on my first small application. It will work with mysql and based on several MainWindows and classes.

    In the Header file of my Main Class I declare the QSqlDatabase Object:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QtSql/QSql>
    #include <QtSql/QSqlDatabase>
    #include <QMessageBox>
    #include <QSqlQuery>
    #include "user.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        QSqlDatabase db;
        User user;
    
    private slots:
        void on_pushButton_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    In the Constructur I will fill the settings and open the connection:

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        // config mysql
        db = QSqlDatabase::addDatabase("QMYSQL", "db");
        db.setHostName("localhost");
        db.setUserName("root");
        db.setPassword("root");
        db.setDatabaseName("mydatabase");
    	
        if (db.open())
        {
            //QMessageBox::information(this, "Connection", "Database connected Succesfully");
        }
        else
        {
            QMessageBox::information(this, "Connection", "Database is not connected Succesfully");
        }
    }
    

    Until here everything is fine.

    Now I like to work with mysql in other classes and MainWindows as well. I think when it run i a class, it will run in an other Window as well.

    I am working on a class:

    #ifndef USER_H
    #define USER_H
    
    #include <QObject>
    #include <QHash>
    #include <QString>
    #include <QSqlQuery>
    #include <QDebug>
    
    class User : public QObject
    {
        Q_OBJECT
    public:
        explicit User(QObject *parent = nullptr);
    
        QHash<QString, QVariant> userinfo;
    
        bool login(QString user_login, QString user_password);
        bool create();
        bool update();
        //bool delete();
    
    signals:
    
    };
    
    #endif // USER_H
    

    Here the code of the class cpp file

    #include "user.h"
    #include "mainwindow.h"
    
    User::User(QObject *parent) : QObject(parent)
    {
    
    }
    
    bool User::login(QString user_login, QString user_password)
    {
        // check user
    
        QString sql = "SELECT * FROM verein_users WHERE user_login = " + user_login;
        QSqlQuery query(sql);
    
        qDebug() << "do sql query";
    
        //int fieldNo = query.record().indexOf("country");
        while (query.next())
        {
            qDebug() << "value: " << query.value("user_name");
            //QString country = query.value(fieldNo).toString();
               //doSomething(country);
        }
    
        return true;
    }
    

    I am working on a login part. I know that my way of coding currently is not good, because of possible sql injections, but I will change it. I will have a running mysql example first.

    When I run that code it gives me the information

    QSqlQuery::exec: database not open

    The help files does not really help. I am not sure. Do I need to declare a QSqlDatabase Object in each window and in each class or how do I get my connection in other classes and windows running?


  • Lifetime Qt Champion

    Hi,

    First thing: don't keep a QSqlDatabase member variable, there's no need for that and it will also trigger a warning when it gets destroyed.

    As for your issue, you gave your database connection a name but you do not use it in your other class. So either use QSqlDatabase::database to retrieve the proper database object to work with.

    However, if you only use one single connection, remove the name you used so the default connection will be used and you won't have to worry about that.



  • Thanks for the hint.

    That helps me.

    It is a bit confusing that visible connection between qsqldatabase and qquery, but its works.


  • Lifetime Qt Champion

    If you take a look at the method signature, you will see that they often take a QSqlDatabase object as last parameter and if you give none, it will use the default connection.


Log in to reply