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. GUI Freeze when terminating the QThread.

GUI Freeze when terminating the QThread.

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 534 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.
  • Q Offline
    Q Offline
    qtwithanzo
    wrote on last edited by
    #1

    Dear all,
    I am using a thread that read data from a sql lite database in a while loop. I do some actions in my main windows based in the data I read in my thread class. I have two button in my GUI. One button start the thread and another button terminate the thread. Now I am facing two issues.

    1. After I terminate the thread, I see my GUI freeze for few seconds.
    2. After the GUI recover, when I try to update the data in the table, I get errorr: QSqlError("5", "Unable to fetch row", "database is locked"). I was believing that after I terminate the thread, my db connection is also closed but seems not.

    I need the help of the experts what I can do to correct my code.

    my code to terminate the thread on button click:

    void MainWindow::on_pushButton_ExitJob_clicked()
    {
        scaraPositions->exit();
        scaraPositions->quit();
        scaraPositions->terminate();
    }
    

    my thread class code:

    #include "scaraPositions.h"
    #include<QDebug>
    #include<QSqlError>
    
    
    
    
    ScaraPositions::ScaraPositions()
    {
        qRegisterMetaType<int64_t>("int64_t");
    
    
        mySqlLiteDB =QSqlDatabase::addDatabase("QSQLITE","3");
        mySqlLiteDB.setDatabaseName(SQLLiteDBPath);
        if(mySqlLiteDB.open())
        {
            qDebug()<<"connected in scara positions";
            mySqlLiteDB.close();
        }
        else
        {
            qDebug()<<"NOT connected in scara positions";
        }
    }
    
    void ScaraPositions::run()
    {
        int joint1;
        int joint2;
        QString position;
        connection:
    
        if(mySqlLiteDB.open())
        {
            while(true)
            {
               QSqlQuery query("",mySqlLiteDB);
               QSqlQuery query1("",mySqlLiteDB);
               query.exec(NextScaraPosition);
    
                 while (query.next()) {
                     counter=0;
                     position = query.value(0).toString();
                     joint1 = query.value(1).toInt();
                     joint2 = query.value(2).toInt();
                     //qDebug()<<"INFO: PROCESSING "<<"position sequence:"<<position;
                     query1.exec(CheckNotMovingJointStatus);
    
                     while (query1.next())
                     {
                         counter++;
                     }
                    query1.finish();
                     if(counter==2)
                       {
                        emit this->sendJoint1Position(joint1,position);
                        emit this->sendJoint2Position(joint2);
                        counter=0;
                        }
                 }
                 query.finish();
            }
        //mySqlLiteDB.close();
        }
      else {
              sleep(5);
              goto connection;
         }
    
    
    }
    
    
    J.HilkJ 1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      You must not use a QSqlDatabase connection created in one thread in another.
      Also you must not store the QSqlDatabase connection in a local member variable. See https://doc.qt.io/qt-5/qsqldatabase.html#details

             QSqlQuery query("",mySqlLiteDB);
             QSqlQuery query1("",mySqlLiteDB);
      

      How is this supposed to work?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      3
      • Q Offline
        Q Offline
        qtwithanzo
        wrote on last edited by
        #3

        Hi @Christian-Ehrlicher thanks for your reply. As per your suggestion, I created a new class dbmanager and added the constructor.
        90f06c70-e8a9-4102-a200-21f5de8d2d90-image.png
        I am using two threads jointstatus.cpp and scarapositions.cpp. Both the classes are reading data from sqllite db. I have created the object of dbmanager class in scarapositions.cpp like

        void ScaraPositions::run()
        {
            DbManager dbManager("ScaraPositions");
        

        and its working as I am calling only the run function of this thread.
        But in the case of jointstatus.cpp, I have several functions which are calling database. I tried putting this line in header file jointstatus.h

        DbManager dbManager;
        

        bit it gives error, DBManager does not name a type.
        Then I tried creating the object of DbManager inside the cpp file, but I get

        QSqlDatabasePrivate::addDatabase: duplicate connection name 'JointStatus1', old connection removed.
        QSqlDatabasePrivate::addDatabase: duplicate connection name 'JointStatus2', old connection removed.
        

        and here is the code of jointstatus.cpp

        void JointStatus::UpdateJoint1Status(QString status)
        {
            DbManager dbManager("JointStatus1");
            if(this->Joint1Status!=status){
                this->Joint1Status=status;
                if(status=="1237"){
                    if (dbManager.isOpen())
                        {
                        dbManager.Joint1StatusMovingUpdate();
                    }
                    }
                    UpdatePositionData(this->positionIdentifier,"Processing");
               }
                else if(status=="1637")
                {
                if (dbManager.isOpen())
                    {
                    dbManager.Joint1StatusNotMovingUpdate();
                }
               }
            //dbManager.~DbManager();
        }
        
        void JointStatus::UpdateJoint2Status(QString status)
        {
            DbManager dbManager("JointStatus2");
            if(this->Joint2Status!=status)
            {
                this->Joint2Status=status;
                if(status=="1237"){
                    if (dbManager.isOpen())
                        {
                        dbManager.Joint2StatusMovingUpdate();
                    }
                }
                else if(status=="1637")
                {
                    if (dbManager.isOpen())
                        {
                        dbManager.Joint2StatusNotMovingUpdate();
                    }
                    UpdatePositionData(this->positionIdentifier,"Completed");
                }
            }
            //dbManager.~DbManager();
        }
        

        I believe I am not following the right way to call the DbManager class. I need to call this DbManager class from my mainwindow and 2 threads so that I can fetch data and take actions.
        Need guidance please.

        1 Reply Last reply
        0
        • Q qtwithanzo

          Dear all,
          I am using a thread that read data from a sql lite database in a while loop. I do some actions in my main windows based in the data I read in my thread class. I have two button in my GUI. One button start the thread and another button terminate the thread. Now I am facing two issues.

          1. After I terminate the thread, I see my GUI freeze for few seconds.
          2. After the GUI recover, when I try to update the data in the table, I get errorr: QSqlError("5", "Unable to fetch row", "database is locked"). I was believing that after I terminate the thread, my db connection is also closed but seems not.

          I need the help of the experts what I can do to correct my code.

          my code to terminate the thread on button click:

          void MainWindow::on_pushButton_ExitJob_clicked()
          {
              scaraPositions->exit();
              scaraPositions->quit();
              scaraPositions->terminate();
          }
          

          my thread class code:

          #include "scaraPositions.h"
          #include<QDebug>
          #include<QSqlError>
          
          
          
          
          ScaraPositions::ScaraPositions()
          {
              qRegisterMetaType<int64_t>("int64_t");
          
          
              mySqlLiteDB =QSqlDatabase::addDatabase("QSQLITE","3");
              mySqlLiteDB.setDatabaseName(SQLLiteDBPath);
              if(mySqlLiteDB.open())
              {
                  qDebug()<<"connected in scara positions";
                  mySqlLiteDB.close();
              }
              else
              {
                  qDebug()<<"NOT connected in scara positions";
              }
          }
          
          void ScaraPositions::run()
          {
              int joint1;
              int joint2;
              QString position;
              connection:
          
              if(mySqlLiteDB.open())
              {
                  while(true)
                  {
                     QSqlQuery query("",mySqlLiteDB);
                     QSqlQuery query1("",mySqlLiteDB);
                     query.exec(NextScaraPosition);
          
                       while (query.next()) {
                           counter=0;
                           position = query.value(0).toString();
                           joint1 = query.value(1).toInt();
                           joint2 = query.value(2).toInt();
                           //qDebug()<<"INFO: PROCESSING "<<"position sequence:"<<position;
                           query1.exec(CheckNotMovingJointStatus);
          
                           while (query1.next())
                           {
                               counter++;
                           }
                          query1.finish();
                           if(counter==2)
                             {
                              emit this->sendJoint1Position(joint1,position);
                              emit this->sendJoint2Position(joint2);
                              counter=0;
                              }
                       }
                       query.finish();
                  }
              //mySqlLiteDB.close();
              }
            else {
                    sleep(5);
                    goto connection;
               }
          
          
          }
          
          
          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @qtwithanzo
          are you aware, you're damning your soul to eternal damnation here ?

           else {
                    sleep(5);
                    goto connection;
               }
          

          😱

          the guy freeze is probably coming from this.

          scaraPositions->exit();
              scaraPositions->quit();
              scaraPositions->terminate();
          

          exit and quit have no meaning/function since you do not use the exec() function/eventloop of the QThread object, you can drop it.

          and terminate relies solely on the operating system to terminate the thread, that my happen immediately or whenever it feels like it.

          also seeing this warning in the documentation:
          https://doc.qt.io/qt-5/qthread.html#terminate

          Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
          

          there is no guarantee that your database is closed correctly, in fact it will be a small miracle if it happens.


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          3
          • Q Offline
            Q Offline
            qtwithanzo
            wrote on last edited by
            #5

            Thanks for your valuable feedback. My screen is not freezing now. :)

            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