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. How to replace QThread with QtConcurrent
Servers for Qt installer are currently down

How to replace QThread with QtConcurrent

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 569 Views 2 Watching
  • 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.
  • M Offline
    M Offline
    Mandeep.Chaudhary
    wrote on last edited by aha_1980
    #1

    I have a SQL fetching class that connects to SQL and fetched the required data.

    I wanted to this in another thread so I did that with QThread. It is working as it should be.

    But now I want to replace it with QTConcurrent. The problem I face with QTconcureent is that I need a connect command that initializes the database before the thread uses to do SQL query.

    Here are my codes created is the public slot and qint64TotalSize is the public method of the SqlFetcher class.

    Controller::Controller(QObject *parent) : QObject(parent)
    {
        SqlFetcher* m_Fetcher = new SqlFetcher();
    
        qInfo() <<"Start"<< QThread::currentThread();
    
         QFutureWatcher<void> watcher;
         QFuture <void> future1 = QtConcurrent::run(m_Fetcher,&SqlFetcher::qint64TotalSize);
    
         watcher.setFuture(future1);
    
    
        //QThread* t1 = new QThread();
        //m_Fetcher->moveToThread(t1);
    
        //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::createDb);
        //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::qint64TotalSize);
        //t1->start();
    
    
        qInfo() <<"Finish"<< QThread::currentThread();
    
    }
    
    void SqlFetcher::qint64TotalSize()
    {
        qint64 l_result= 0;
        QSqlQuery l_query;
    
        if (m_sqldb.isValid())
        {
            m_sqldb.open();
    
            if ((m_sqldb.isOpen()))
            {
                l_query.prepare("SELECT COUNT(*) FROM table1");
                l_query.exec();
    
                if (l_query.next()) {
                    l_result= l_query.value(0).toInt();
                }
                m_sqldb.close();
            }
        }
    
        qInfo() << l_result << QThread::currentThread();
    }
    
    void SqlFetcher::createDb()
    {
        m_sqldb = QSqlDatabase::addDatabase("QSQLITE");
        m_sqldb.setDatabaseName("xyz.db");
         qInfo() << "createDB" << QThread::currentThread();
    }
    

    My current output is

    Start QThread(0x7feab4c0f060)
    Finish QThread(0x7feab4c0f060)
    0 QThread(0x7feab4d42070, name = "Thread (pooled)")
    

    Expected Output or Output with Qthread is

    Start QThread(0x7fe82140f060)
    Finish QThread(0x7fe82140f060)
    createDB QThread(0x7fe82155c840)
    151 QThread(0x7fe82155c840)
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #4

      From what you wrote, you didn't follow any of my advices.

      Again: Read the QSqlDatabase documentation, the QSqlDatabase::database method documentation and this QSqlQuery constructor documentation.

      Again: You have to create a separate named connection for each thread you are using to connect to your database.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        No, the connection to the database needs to be done within the thread. You can't re-use the same connection in several different threads. Create a new named connection each time your run your worker object.
        Also, don't keep a QSqlDatabase object as member variable. Read the QSqlDatabase documentation to see how to retrieve the correct connection when needed.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • M Offline
          M Offline
          Mandeep.Chaudhary
          wrote on last edited by Mandeep.Chaudhary
          #3

          Thank You for the reply.

          I tried this by editing qint64TotalSize() to make sure connection is within the thread like

          void SqlFetcher::qint64TotalSize()
          {
              qint64 l_result= 0;
              QSqlQuery l_query;
          
              if (!m_sqldb.isValid())
              {
                  createDb();
              }
          
              m_sqldb.open();
          
              if ((m_sqldb.isOpen()))
              {
                  l_query.prepare("SELECT COUNT(*) FROM table1");
                  l_query.exec();
          
                  if (l_query.next()) {
                      l_result= l_query.value(0).toInt();
                  }
                  m_sqldb.close();
              }
          
              qInfo() << l_result << QThread::currentThread();
          }
          

          but the output is

          Start QThread(0x7fec9cc0f060)
          Finish QThread(0x7fec9cc0f060)
          createDB QThread(0x7fec9f0a65d0, name = "Thread (pooled)")
          QSqlQuery::prepare: database not open
          0 QThread(0x7fec9f0a65d0, name = "Thread (pooled)")
          
          KroMignonK 1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            From what you wrote, you didn't follow any of my advices.

            Again: Read the QSqlDatabase documentation, the QSqlDatabase::database method documentation and this QSqlQuery constructor documentation.

            Again: You have to create a separate named connection for each thread you are using to connect to your database.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            3
            • M Mandeep.Chaudhary

              Thank You for the reply.

              I tried this by editing qint64TotalSize() to make sure connection is within the thread like

              void SqlFetcher::qint64TotalSize()
              {
                  qint64 l_result= 0;
                  QSqlQuery l_query;
              
                  if (!m_sqldb.isValid())
                  {
                      createDb();
                  }
              
                  m_sqldb.open();
              
                  if ((m_sqldb.isOpen()))
                  {
                      l_query.prepare("SELECT COUNT(*) FROM table1");
                      l_query.exec();
              
                      if (l_query.next()) {
                          l_result= l_query.value(0).toInt();
                      }
                      m_sqldb.close();
                  }
              
                  qInfo() << l_result << QThread::currentThread();
              }
              

              but the output is

              Start QThread(0x7fec9cc0f060)
              Finish QThread(0x7fec9cc0f060)
              createDB QThread(0x7fec9f0a65d0, name = "Thread (pooled)")
              QSqlQuery::prepare: database not open
              0 QThread(0x7fec9f0a65d0, name = "Thread (pooled)")
              
              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #5

              @Mandeep-Chaudhary As @SGaist has written, is not allowed to use a QSqlConnection() outside from the thread in which it has been created/initialized.
              If you want to do multithreading and don't want your application to crash, you have to follow this!

              Take a look at this post: https://forum.qt.io/post/533583, it is about SQLite Database, but it is easy to port to another kind of DB.

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              1 Reply Last reply
              1
              • M Offline
                M Offline
                Mandeep.Chaudhary
                wrote on last edited by Mandeep.Chaudhary
                #6

                Thank You guys for the reply. I undesrtood what you guys are saying but as I am new to QT so keeps on getting confused.

                What you guys saying make sense with examples in mentioned threads I succeeded.

                Thank You !!!

                1 Reply Last reply
                0

                • Login

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