Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Returning QSqlQueryModel for TableView
Forum Updated to NodeBB v4.3 + New Features

Returning QSqlQueryModel for TableView

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 4 Posters 2.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by jsulm
    #6

    @masa4 said in Returning QSqlQueryModel for TableView:

    And I want to use db object in several classes

    Don't do that!
    It is clearly stated in red in the documentation why you should not do that (https://doc.qt.io/qt-6/qsqldatabase.html):
    "Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior."

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    3
    • E Offline
      E Offline
      Emre MUTLU
      wrote on last edited by
      #7
      DB *db = new DB; 
      QSqlQueryModel *model=new QSqlQueryModel;
      model->setQuery(db->SelectData());
      ui->tableView->setModel(model);
      delete db;//closed and deleted db objects
      

      db.cpp:

      DB::~DB()//db destructor
      {
      database.close();
      QSqlDatabase::removeDatabase("qt_sql_default_connection");//your dbname here
      }
      

      example class.cpp:

      {
      DB *db=new DB;
      do something
      delete db;
      }
      

      example class1.cpp:

      DB *db=new DB;
      do something
      delete db;//we deleting db object and its call DB destructor
      
      M 1 Reply Last reply
      1
      • E Emre MUTLU
        DB *db = new DB; 
        QSqlQueryModel *model=new QSqlQueryModel;
        model->setQuery(db->SelectData());
        ui->tableView->setModel(model);
        delete db;//closed and deleted db objects
        

        db.cpp:

        DB::~DB()//db destructor
        {
        database.close();
        QSqlDatabase::removeDatabase("qt_sql_default_connection");//your dbname here
        }
        

        example class.cpp:

        {
        DB *db=new DB;
        do something
        delete db;
        }
        

        example class1.cpp:

        DB *db=new DB;
        do something
        delete db;//we deleting db object and its call DB destructor
        
        M Offline
        M Offline
        masa4
        wrote on last edited by masa4
        #8

        @Emre-MUTLU
        constructor:

        DB::DB(const QString &path)
        {
            m_db = QSqlDatabase::addDatabase("QSQLITE");
            m_db.setDatabaseName(path);
        
            if(!m_db.open())
                qDebug() << "Error: connection with database failed";
            else
                qDebug() << "Database: connection ok";
            qDebug() << m_db.lastError().text();
        }
        

        destructor:

        DB::~DB()
        {
            m_db.close();
            m_db.removeDatabase("mypath"); //value of "path"  variable in constructor
        }
        

        and i got:

        Database: connection ok
        ""
        QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
        Database: connection ok
        ""
        ""
        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.
        Database: connection ok
        ""
        QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
        Database: connection ok
        ""
        QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
        Database: connection ok
        ""
        ""
        

        Every time new db oject instantiated with DB db = new DB(); i got these errors. Im using delete db like you recommended.

        jsulmJ E 2 Replies Last reply
        0
        • E Offline
          E Offline
          Emre MUTLU
          wrote on last edited by
          #9
          DB::~DB()
          {
              m_db.close();
              m_db.removeDatabase("qt_sql_default_connection"); 
          }
          
          1 Reply Last reply
          0
          • M masa4

            @Emre-MUTLU
            constructor:

            DB::DB(const QString &path)
            {
                m_db = QSqlDatabase::addDatabase("QSQLITE");
                m_db.setDatabaseName(path);
            
                if(!m_db.open())
                    qDebug() << "Error: connection with database failed";
                else
                    qDebug() << "Database: connection ok";
                qDebug() << m_db.lastError().text();
            }
            

            destructor:

            DB::~DB()
            {
                m_db.close();
                m_db.removeDatabase("mypath"); //value of "path"  variable in constructor
            }
            

            and i got:

            Database: connection ok
            ""
            QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
            Database: connection ok
            ""
            ""
            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.
            Database: connection ok
            ""
            QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
            Database: connection ok
            ""
            QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
            Database: connection ok
            ""
            ""
            

            Every time new db oject instantiated with DB db = new DB(); i got these errors. Im using delete db like you recommended.

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #10

            @masa4 There is really no need to add same database connection again and again. Do it once and use it. That is why I pointed you to the documentation. You can get existing database at any time in any place of your application using https://doc.qt.io/qt-6/qsqldatabase.html#database

            To analyse the errors you posted: how many DB instances do you have at the same time? Because each of them will try to add same database...

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • M masa4

              @Emre-MUTLU
              constructor:

              DB::DB(const QString &path)
              {
                  m_db = QSqlDatabase::addDatabase("QSQLITE");
                  m_db.setDatabaseName(path);
              
                  if(!m_db.open())
                      qDebug() << "Error: connection with database failed";
                  else
                      qDebug() << "Database: connection ok";
                  qDebug() << m_db.lastError().text();
              }
              

              destructor:

              DB::~DB()
              {
                  m_db.close();
                  m_db.removeDatabase("mypath"); //value of "path"  variable in constructor
              }
              

              and i got:

              Database: connection ok
              ""
              QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
              Database: connection ok
              ""
              ""
              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.
              Database: connection ok
              ""
              QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
              Database: connection ok
              ""
              QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
              Database: connection ok
              ""
              ""
              

              Every time new db oject instantiated with DB db = new DB(); i got these errors. Im using delete db like you recommended.

              E Offline
              E Offline
              Emre MUTLU
              wrote on last edited by Emre MUTLU
              #11

              @masa4

              DB::~DB()
              {
                  m_db.close();
                  m_db.removeDatabase(mypath); your path is string value already so you dont need to use(");
              }`
              
              JonBJ M 2 Replies Last reply
              0
              • E Emre MUTLU

                @masa4

                DB::~DB()
                {
                    m_db.close();
                    m_db.removeDatabase(mypath); your path is string value already so you dont need to use(");
                }`
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #12

                @Emre-MUTLU , @masa4
                Up to you, but as @jsulm/documentation states you really should not have a QSqlDatabase m_db member variable in a class. If you need to access the QSqlDatabase instance use static QSqlDatabase QSqlDatabase::database().

                E 1 Reply Last reply
                2
                • JonBJ JonB

                  @Emre-MUTLU , @masa4
                  Up to you, but as @jsulm/documentation states you really should not have a QSqlDatabase m_db member variable in a class. If you need to access the QSqlDatabase instance use static QSqlDatabase QSqlDatabase::database().

                  E Offline
                  E Offline
                  Emre MUTLU
                  wrote on last edited by
                  #13

                  @JonB

                  DB::~DB()
                  {
                      m_db.close();
                     m_db=QSqlDatabase();
                      m_db.removeDatabase(mypath); your path is string value already so you dont need to use(");
                  }
                  

                  like that?

                  JonBJ 1 Reply Last reply
                  0
                  • E Emre MUTLU

                    @JonB

                    DB::~DB()
                    {
                        m_db.close();
                       m_db=QSqlDatabase();
                        m_db.removeDatabase(mypath); your path is string value already so you dont need to use(");
                    }
                    

                    like that?

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #14

                    @Emre-MUTLU
                    No! You have a QSqlDatabase m_db member variable in your DB class. Start by getting rid of that variable and then make your code work! Remember that instead you can re-access the current database instance via QSqlDatabase::database() if you need it. You may have QSqlDatabase db variables local to methods if you wish, but no class member variable which persists for the lifetime of the class.

                    M 1 Reply Last reply
                    2
                    • JonBJ JonB

                      @Emre-MUTLU
                      No! You have a QSqlDatabase m_db member variable in your DB class. Start by getting rid of that variable and then make your code work! Remember that instead you can re-access the current database instance via QSqlDatabase::database() if you need it. You may have QSqlDatabase db variables local to methods if you wish, but no class member variable which persists for the lifetime of the class.

                      M Offline
                      M Offline
                      masa4
                      wrote on last edited by
                      #15

                      @jsulm @JonB So you guys mean change code to like:

                      DB::DB(const QString &path)
                      {
                          QSqlDatabase::addDatabase("QSQLITE");
                          QSqlDatabase.setDatabaseName(path); //this doesnt work, the method is not static.
                      
                          if(!QSqlDatabase::open()) //non static, not work
                              qDebug() << "Error: connection with database failed";
                          else
                              qDebug() << "Database: connection ok";
                          qDebug() << QSqlDatabase::lastError().text(); //non static, not work
                      }
                      

                      I got errors from nonstatic functions in this way. And secondly if i try to call from another class( selectData() is method of DB class.)
                      otherclass.cpp:

                      //db = new DB();
                      //model->setQuery(db->selectData(ui->lineedit->text())); //normally its in this way
                      model->setQuery(QSqlDatabase::database().selectData(ui->lineedit->text())); //No member named 'selectData' in 'QSqlDatabase'
                      

                      How should i modify my class actually?

                      jsulmJ 1 Reply Last reply
                      0
                      • M masa4

                        @jsulm @JonB So you guys mean change code to like:

                        DB::DB(const QString &path)
                        {
                            QSqlDatabase::addDatabase("QSQLITE");
                            QSqlDatabase.setDatabaseName(path); //this doesnt work, the method is not static.
                        
                            if(!QSqlDatabase::open()) //non static, not work
                                qDebug() << "Error: connection with database failed";
                            else
                                qDebug() << "Database: connection ok";
                            qDebug() << QSqlDatabase::lastError().text(); //non static, not work
                        }
                        

                        I got errors from nonstatic functions in this way. And secondly if i try to call from another class( selectData() is method of DB class.)
                        otherclass.cpp:

                        //db = new DB();
                        //model->setQuery(db->selectData(ui->lineedit->text())); //normally its in this way
                        model->setQuery(QSqlDatabase::database().selectData(ui->lineedit->text())); //No member named 'selectData' in 'QSqlDatabase'
                        

                        How should i modify my class actually?

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #16

                        @masa4 said in Returning QSqlQueryModel for TableView:

                        So you guys mean change code to like

                        No, we only suggested to not to have the m_db member variable in your DB class. I don't know why you changed model->setQuery part.

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        M 1 Reply Last reply
                        0
                        • jsulmJ jsulm

                          @masa4 said in Returning QSqlQueryModel for TableView:

                          So you guys mean change code to like

                          No, we only suggested to not to have the m_db member variable in your DB class. I don't know why you changed model->setQuery part.

                          M Offline
                          M Offline
                          masa4
                          wrote on last edited by
                          #17

                          @jsulm Ho okay i see, so I will continue to use

                          db = new DB();
                          some code
                          delete DB();
                          

                          paradigm, right? And what can u say for other non static methods? Without m_db how will i use them? In destructor i cant use QSqlDatabase::close() without member variable too.

                          jsulmJ 1 Reply Last reply
                          0
                          • E Emre MUTLU

                            @masa4

                            DB::~DB()
                            {
                                m_db.close();
                                m_db.removeDatabase(mypath); your path is string value already so you dont need to use(");
                            }`
                            
                            M Offline
                            M Offline
                            masa4
                            wrote on last edited by
                            #18

                            @Emre-MUTLU No no i mean i used same path in both sides.
                            constructor:

                            m_db.setDatabaseName(DB_PATH);
                            

                            destructor

                            m_db.removeDatabase(DB_PATH);
                            

                            I am passing same value to both but i keep getting this error every time new DB(); called i think:

                            QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
                            
                            E 1 Reply Last reply
                            0
                            • M masa4

                              @jsulm Ho okay i see, so I will continue to use

                              db = new DB();
                              some code
                              delete DB();
                              

                              paradigm, right? And what can u say for other non static methods? Without m_db how will i use them? In destructor i cant use QSqlDatabase::close() without member variable too.

                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #19

                              @masa4 said in Returning QSqlQueryModel for TableView:

                              And what can u say for other non static methods? Without m_db how will i use them?

                              Which non static members do you mean? As already explained you can get the database instance you need by simply calling QSqlDatabase::database().

                              And with your current implementation you're still creating the connection everytime you create a DB instance. You should use https://doc.qt.io/qt-6/qsqldatabase.html#contains to check whether the connection already exist and only add the connection if it does not yet exist.

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              M 1 Reply Last reply
                              1
                              • M masa4

                                @Emre-MUTLU No no i mean i used same path in both sides.
                                constructor:

                                m_db.setDatabaseName(DB_PATH);
                                

                                destructor

                                m_db.removeDatabase(DB_PATH);
                                

                                I am passing same value to both but i keep getting this error every time new DB(); called i think:

                                QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
                                
                                E Offline
                                E Offline
                                Emre MUTLU
                                wrote on last edited by
                                #20

                                @masa4
                                i think you db name defaultly is qt_sql_default_connection

                                QSqlDatabase::removeDatabase("qt_sql_default_connection");
                                

                                try this

                                M 1 Reply Last reply
                                1
                                • jsulmJ jsulm

                                  @masa4 said in Returning QSqlQueryModel for TableView:

                                  And what can u say for other non static methods? Without m_db how will i use them?

                                  Which non static members do you mean? As already explained you can get the database instance you need by simply calling QSqlDatabase::database().

                                  And with your current implementation you're still creating the connection everytime you create a DB instance. You should use https://doc.qt.io/qt-6/qsqldatabase.html#contains to check whether the connection already exist and only add the connection if it does not yet exist.

                                  M Offline
                                  M Offline
                                  masa4
                                  wrote on last edited by
                                  #21

                                  @jsulm You mean like this? :

                                  DB::DB(const QString &path)
                                  {
                                      if(!QSqlDatabase::contains(QSqlDatabase::database().connectionName())){
                                              QSqlDatabase::addDatabase("QSQLITE");
                                              QSqlDatabase::database().setDatabaseName(path);
                                      }
                                  
                                      if(!QSqlDatabase::database().open())
                                          qDebug() << "Error: connection with database failed";
                                      else
                                          qDebug() << "Database: connection ok";
                                      qDebug() << QSqlDatabase::database().lastError().text();
                                  }
                                  DB::~DB()
                                  {
                                      QSqlDatabase::database().close();
                                  }
                                  
                                  JonBJ 1 Reply Last reply
                                  0
                                  • E Emre MUTLU

                                    @masa4
                                    i think you db name defaultly is qt_sql_default_connection

                                    QSqlDatabase::removeDatabase("qt_sql_default_connection");
                                    

                                    try this

                                    M Offline
                                    M Offline
                                    masa4
                                    wrote on last edited by
                                    #22

                                    @Emre-MUTLU Yes when i add this i dont see the error output, but i changed the code again.

                                    1 Reply Last reply
                                    0
                                    • M masa4

                                      @jsulm You mean like this? :

                                      DB::DB(const QString &path)
                                      {
                                          if(!QSqlDatabase::contains(QSqlDatabase::database().connectionName())){
                                                  QSqlDatabase::addDatabase("QSQLITE");
                                                  QSqlDatabase::database().setDatabaseName(path);
                                          }
                                      
                                          if(!QSqlDatabase::database().open())
                                              qDebug() << "Error: connection with database failed";
                                          else
                                              qDebug() << "Database: connection ok";
                                          qDebug() << QSqlDatabase::database().lastError().text();
                                      }
                                      DB::~DB()
                                      {
                                          QSqlDatabase::database().close();
                                      }
                                      
                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by JonB
                                      #23

                                      @masa4
                                      If it helps, you are welcome to use a local variable in a method to reference a database, just that you should not keep it around in a class member variable. You might have code looking like this (only a suggestion):

                                      DB::DB(const QString &path)
                                      {
                                          QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
                                          db.setDatabaseName(path);
                                          if (!db.open())
                                              qDebug() << db.lastError().text();
                                      }
                                      
                                      DB::~DB()
                                      {
                                          bool valid = false;
                                          QString connectionName = "";
                                          {
                                              // the need for these enclosing parentheses for scope is explained at https://doc.qt.io/qt-6/qsqldatabase.html#removeDatabase
                                              // only because I am going to call `removeDatabase()` here
                                              QSqlDatabase db = QSqlDatabase::database();
                                              valid = db.isValid();
                                              if (valid)
                                              {
                                                  connectionName = db.connectionName();
                                                  if (db.isOpen())
                                                      db.close();
                                              }
                                          }
                                          if (valid && !connectionName.isEmpty())
                                              QSqlDatabase::removeDatabase(connectionName);
                                      }
                                      
                                      1 Reply Last reply
                                      1

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved