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. What is good way to update the Progressbar value?
QtWS25 Last Chance

What is good way to update the Progressbar value?

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 2.1k 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.
  • Y Offline
    Y Offline
    Yash001
    wrote on last edited by
    #1

    Hi,
    Here I wrote some code for the updating the Progress bar value. I don't know about the what is right way to update the Progress bar. Here I mention some code.

    /*************** RecoveryLoader. h *******************/
    #pragma once
    #include <global_typedefs.h>
    #include <QThread>
    #include <qtimer.h>
    #include <qeventloop.h>

    #define EXIT_CORRECTLY 0
    #define EXIT_INCORRECTLY 1

    class RecoveryProcessLoader : public QObject
    {
    Q_OBJECT
    public:
    static RecoveryProcessLoader* Instance();
    public:
    void RecordReceiveByte(const uint NumberOfReceiveByte);
    void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);

    signals :
    void ProgressChanged(int);
    void Finished(bool);
    void Started();

    public slots:
    void dataReceiveingSwitch(bool);
    void dataReceivePing();

    void setProgressbarValue();
    

    private:
    RecoveryProcessLoader();
    ~RecoveryProcessLoader();
    uint getPageSize(const HardwareModel_t);
    volatile uint numberOfReceiveByte;
    volatile uint totalNumberOfbyte;
    QThread progressBarThread;
    static uint previousProgressBarValue;

    };

    /**************************RecoveryLoader.cpp ***********/
    #include "RecoveryLoader.h"

    RecoveryProcessLoader* RecoveryProcessLoader::Instance() {
    static RecoveryProcessLoader * ret = 0;
    if (0 == ret) {
    ret = new RecoveryProcessLoader;
    }
    return ret;
    }

    RecoveryProcessLoader::RecoveryProcessLoader(){
    QObject::connect(&progressBarThread, &QThread::started, this, &RecoveryProcessLoader::setProgressbarValue);
    }

    RecoveryProcessLoader::~RecoveryProcessLoader() {
    QObject::disconnect(&progressBarThread, &QThread::started, this, &RecoveryProcessLoader::setProgressbarValue);
    }

    uint RecoveryProcessLoader:: getPageSize(const HardwareModel_t HWversion) {
    return pageSizeOfFlash;
    }

    void RecoveryProcessLoader::calculateTotalBytes(const HardwareModel_t HWversion,const uint32_t numPagesUsed) {
    numberOfReceiveByte = 0;
    auto pageSize = getPageSize(HWversion);
    totalNumberOfbyte = pageSize * numPagesUsed;
    }

    void RecoveryProcessLoader::RecordReceiveByte(const uint numberOfByte) {
    numberOfReceiveByte += numberOfByte;
    }

    void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
    if (dataRxSwitch) {
    emit Started();
    emit ProgressChanged(0);
    progressBarThread.start();
    this->moveToThread(&progressBarThread);
    }
    else {
    progressBarThread.exit(EXIT_CORRECTLY);
    emit Finished(true);
    }
    }

    // tricky way use for come out from the "Do while" loop. (Data start and Stop bit is use for exit do while loop)
    // Progress bar does not give the Exact value for number of Receiving Data bytes.
    // Error is not checking while recovering the Data.

    //void RecoveryProcessLoader::run() {
    // emit Started();
    // bool noError = true;
    //
    // emit ProgressChanged(0);
    // do {
    // emit ProgressChanged((numberOfReceiveByte *100) / totalNumberOfbyte);
    // } while (dataRx);
    //
    // emit Finished(noError);
    //}

    void RecoveryProcessLoader::setProgressbarValue() {
    QEventLoop loop;
    QTimer timer;
    timer.setInterval(1000);

    QEventLoop *loopPtr = &loop;
    

    #define EXIT_BY_TIMER 1
    #define EXIT_BY_PING 0

    QList<QMetaObject::Connection> connections;
    
    connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=]() {
    	emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
    	loopPtr->exit(EXIT_BY_PING);
    });
    
    connections << connect(&timer, &QTimer::timeout, [=]() {
    	loopPtr->exit(EXIT_BY_TIMER);
    });
    
    timer.start();
    int ret = loop.exec();
    timer.stop();
    
    foreach(auto conn, connections) {
    	disconnect(conn);
    }
    
    if (ret != EXIT_BY_PING) {
    	progressBarThread.exit(EXIT_INCORRECTLY);
    	emit Finished(false);
    	return;
    }
    

    }

    I am getting the Error for siganl dataRecivePing Signal. what is wrong with that signal. ??

    Here the Error
    0_1529618538455_c1d48e58-0487-47e0-863b-331a2157f041-image.png

    if any other good way is to updating the progress bar then please let me know.

    jsulmJ 1 Reply Last reply
    0
    • Y Yash001

      Hi,
      Here I wrote some code for the updating the Progress bar value. I don't know about the what is right way to update the Progress bar. Here I mention some code.

      /*************** RecoveryLoader. h *******************/
      #pragma once
      #include <global_typedefs.h>
      #include <QThread>
      #include <qtimer.h>
      #include <qeventloop.h>

      #define EXIT_CORRECTLY 0
      #define EXIT_INCORRECTLY 1

      class RecoveryProcessLoader : public QObject
      {
      Q_OBJECT
      public:
      static RecoveryProcessLoader* Instance();
      public:
      void RecordReceiveByte(const uint NumberOfReceiveByte);
      void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);

      signals :
      void ProgressChanged(int);
      void Finished(bool);
      void Started();

      public slots:
      void dataReceiveingSwitch(bool);
      void dataReceivePing();

      void setProgressbarValue();
      

      private:
      RecoveryProcessLoader();
      ~RecoveryProcessLoader();
      uint getPageSize(const HardwareModel_t);
      volatile uint numberOfReceiveByte;
      volatile uint totalNumberOfbyte;
      QThread progressBarThread;
      static uint previousProgressBarValue;

      };

      /**************************RecoveryLoader.cpp ***********/
      #include "RecoveryLoader.h"

      RecoveryProcessLoader* RecoveryProcessLoader::Instance() {
      static RecoveryProcessLoader * ret = 0;
      if (0 == ret) {
      ret = new RecoveryProcessLoader;
      }
      return ret;
      }

      RecoveryProcessLoader::RecoveryProcessLoader(){
      QObject::connect(&progressBarThread, &QThread::started, this, &RecoveryProcessLoader::setProgressbarValue);
      }

      RecoveryProcessLoader::~RecoveryProcessLoader() {
      QObject::disconnect(&progressBarThread, &QThread::started, this, &RecoveryProcessLoader::setProgressbarValue);
      }

      uint RecoveryProcessLoader:: getPageSize(const HardwareModel_t HWversion) {
      return pageSizeOfFlash;
      }

      void RecoveryProcessLoader::calculateTotalBytes(const HardwareModel_t HWversion,const uint32_t numPagesUsed) {
      numberOfReceiveByte = 0;
      auto pageSize = getPageSize(HWversion);
      totalNumberOfbyte = pageSize * numPagesUsed;
      }

      void RecoveryProcessLoader::RecordReceiveByte(const uint numberOfByte) {
      numberOfReceiveByte += numberOfByte;
      }

      void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
      if (dataRxSwitch) {
      emit Started();
      emit ProgressChanged(0);
      progressBarThread.start();
      this->moveToThread(&progressBarThread);
      }
      else {
      progressBarThread.exit(EXIT_CORRECTLY);
      emit Finished(true);
      }
      }

      // tricky way use for come out from the "Do while" loop. (Data start and Stop bit is use for exit do while loop)
      // Progress bar does not give the Exact value for number of Receiving Data bytes.
      // Error is not checking while recovering the Data.

      //void RecoveryProcessLoader::run() {
      // emit Started();
      // bool noError = true;
      //
      // emit ProgressChanged(0);
      // do {
      // emit ProgressChanged((numberOfReceiveByte *100) / totalNumberOfbyte);
      // } while (dataRx);
      //
      // emit Finished(noError);
      //}

      void RecoveryProcessLoader::setProgressbarValue() {
      QEventLoop loop;
      QTimer timer;
      timer.setInterval(1000);

      QEventLoop *loopPtr = &loop;
      

      #define EXIT_BY_TIMER 1
      #define EXIT_BY_PING 0

      QList<QMetaObject::Connection> connections;
      
      connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=]() {
      	emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
      	loopPtr->exit(EXIT_BY_PING);
      });
      
      connections << connect(&timer, &QTimer::timeout, [=]() {
      	loopPtr->exit(EXIT_BY_TIMER);
      });
      
      timer.start();
      int ret = loop.exec();
      timer.stop();
      
      foreach(auto conn, connections) {
      	disconnect(conn);
      }
      
      if (ret != EXIT_BY_PING) {
      	progressBarThread.exit(EXIT_INCORRECTLY);
      	emit Finished(false);
      	return;
      }
      

      }

      I am getting the Error for siganl dataRecivePing Signal. what is wrong with that signal. ??

      Here the Error
      0_1529618538455_c1d48e58-0487-47e0-863b-331a2157f041-image.png

      if any other good way is to updating the progress bar then please let me know.

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

      @Yash001 You put void dataReceivePing() under slots.
      Also, I don't know exactly all your code, but I'm wondering why you need an event loop to update the progress bar. Usually you have a signal which provides a new progress value which you then set in the slot.

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

      1 Reply Last reply
      2
      • Y Offline
        Y Offline
        Yash001
        wrote on last edited by
        #3

        thank you @jsulm. I transfer into the signal area., and it is work. I need to Qevent loop because of the dataReceivePing() signal is generated whenever the data is received from hardware. if it is not received then i wanted to exit from the thread loop.

        1 Reply Last reply
        0
        • Y Offline
          Y Offline
          Yash001
          wrote on last edited by
          #4

          void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {

          if (dataRxSwitch) {
          	emit Started();
          	emit ProgressChanged(0);
          	this->moveToThread(&progressBarThread);
          	progressBarThread.start();
          	
          }
          else {
          	progressBarThread.exit(); // need to work here, immidiatly stop the Thread after creating. yash 
          	//progressBarThread.exit(EXIT_CORRECTLY);
          	emit Finished(true);
          }
          

          }

          void RecoveryProcessLoader::setProgressbarValue() {
          QEventLoop loop;
          QTimer timer;
          timer.setInterval(1000);

          QEventLoop *loopPtr = &loop;
          

          #define EXIT_BY_TIMER 1
          #define EXIT_BY_PING 0

          QList<QMetaObject::Connection> connections;
          
          connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=]() {
          	emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
          	loopPtr->exit(EXIT_BY_PING);
          });
          
          connections << connect(&timer, &QTimer::timeout, [=]() {
          	loopPtr->exit(EXIT_BY_TIMER);
          });
          
          timer.start();
          int ret = loop.exec();
          timer.stop();
          
          foreach(auto conn, connections) {
          	disconnect(conn);
          }
          
          if (ret != EXIT_BY_PING) {
          	progressBarThread.quit();
          	emit Finished(false);
          	return;
          }
          

          }
          Here One More Issue is created. if the dataReceiveingSwitch signal received 2 times. true and false. Then thread should immediately exit. but it won't.
          if first time : datarxswitch value is true; thread start to run .
          second time it is false; thread exit .

          whenever I received false at that time i wanted to immediately exit from the thread. first two time pointer git in to dataReceiveingSwitch. it is right but after that it is also hit into setProgressbarValue(). i don't want that things.

          how can i stop immediately stop thread execution. after receiving false into dataReceiveingSwitch signal.

          jsulmJ 1 Reply Last reply
          0
          • Y Yash001

            void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {

            if (dataRxSwitch) {
            	emit Started();
            	emit ProgressChanged(0);
            	this->moveToThread(&progressBarThread);
            	progressBarThread.start();
            	
            }
            else {
            	progressBarThread.exit(); // need to work here, immidiatly stop the Thread after creating. yash 
            	//progressBarThread.exit(EXIT_CORRECTLY);
            	emit Finished(true);
            }
            

            }

            void RecoveryProcessLoader::setProgressbarValue() {
            QEventLoop loop;
            QTimer timer;
            timer.setInterval(1000);

            QEventLoop *loopPtr = &loop;
            

            #define EXIT_BY_TIMER 1
            #define EXIT_BY_PING 0

            QList<QMetaObject::Connection> connections;
            
            connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=]() {
            	emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
            	loopPtr->exit(EXIT_BY_PING);
            });
            
            connections << connect(&timer, &QTimer::timeout, [=]() {
            	loopPtr->exit(EXIT_BY_TIMER);
            });
            
            timer.start();
            int ret = loop.exec();
            timer.stop();
            
            foreach(auto conn, connections) {
            	disconnect(conn);
            }
            
            if (ret != EXIT_BY_PING) {
            	progressBarThread.quit();
            	emit Finished(false);
            	return;
            }
            

            }
            Here One More Issue is created. if the dataReceiveingSwitch signal received 2 times. true and false. Then thread should immediately exit. but it won't.
            if first time : datarxswitch value is true; thread start to run .
            second time it is false; thread exit .

            whenever I received false at that time i wanted to immediately exit from the thread. first two time pointer git in to dataReceiveingSwitch. it is right but after that it is also hit into setProgressbarValue(). i don't want that things.

            how can i stop immediately stop thread execution. after receiving false into dataReceiveingSwitch signal.

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

            @Yash001 I don't understand the need for a thread at all. Why do you think you need one? If you already get a signal to update the progress bar then there is really no need for a thread.

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

            Y 1 Reply Last reply
            2
            • jsulmJ jsulm

              @Yash001 I don't understand the need for a thread at all. Why do you think you need one? If you already get a signal to update the progress bar then there is really no need for a thread.

              Y Offline
              Y Offline
              Yash001
              wrote on last edited by
              #6

              @jsulm.
              I want two functionality should work parallel.

              1. Thread One (Main thread);
                - Write the Data into File
                - Remove the Widgets if the Data Reeving completed ( few button and Progress bar dialog)

              2. another thread need to update progress bar.

              before you advise about Qthread I wrote this code. funcanality is work perfect.

              .h file

              #pragma once
              
              #include <global_typedefs.h>
              #include <QThread>
              #include <qtimer.h>
              #include <qeventloop.h>
              
              #define EXIT_CORRECTLY 0
              #define EXIT_INCORRECTLY 1
              
              class RecoveryProcessLoader : public QThread
              {
              	Q_OBJECT
              public:
              	static RecoveryProcessLoader* Instance();
              
              public:
              	 void RecordReceiveByte(const uint NumberOfReceiveByte);
              	 void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);
              	 
              signals :
              	void ProgressChanged(int);
              	void Finished(bool);
              	void Started();
              	void dataReceivePing();
              	
              public slots:
              	void dataReceiveingSwitch(bool);
              
              private:
              	RecoveryProcessLoader();
              	uint getPageSize(const HardwareModel_t);
              	volatile uint numberOfReceiveByte;
              	volatile uint totalNumberOfbyte;
              	bool previousSignalVal = false;
              	void run();
              };
              

              .cpp file

              #include "RecoveryLoader.h"
              
              
              RecoveryProcessLoader* RecoveryProcessLoader::Instance() {
              	static RecoveryProcessLoader * ret = 0 ;
              	if (0 == ret) {
              		ret = new RecoveryProcessLoader;
              	}
              	return ret;
              }
              
              RecoveryProcessLoader::RecoveryProcessLoader(){
              	//this->moveToThread(this);
              }
              
              uint RecoveryProcessLoader::getPageSize(const HardwareModel_t HWversion) {
              
              
              	return pageSizeOfFlash;
              }
              
              
              void RecoveryProcessLoader::calculateTotalBytes(const HardwareModel_t HWversion,const uint32_t numPagesUsed) {
              	numberOfReceiveByte = 0;
              	auto pageSize = getPageSize(HWversion);
              	totalNumberOfbyte = pageSize * 1;
              	return;
              	totalNumberOfbyte = pageSize * numPagesUsed;
              }
              
              void RecoveryProcessLoader::RecordReceiveByte(const uint numberOfByte) {
              	numberOfReceiveByte += numberOfByte;
              }
              
              void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
              	
              	if (dataRxSwitch && (!previousSignalVal)) {
              		
              		previousSignalVal = true;
              
              		emit ProgressChanged(0);
              		emit Started();
              		this->start();
              	}
              	else if ((!dataRxSwitch) &&(previousSignalVal)){
              		previousSignalVal = false;
              		
              		this->exit(EXIT_CORRECTLY);
              		if (!this->isFinished()) {
              			this->wait();
              		}
              
              		emit ProgressChanged(100);
              		emit Finished(true);
              		
              	}
              	else {
              		NULL;
              	}
              }
              
              // This Thread may through wrong value for Finished signal if the dataReceiveingSwitch signal does not received in correct order.
              #define EXIT_BY_TIMER	1
              #define EXIT_BY_PING	0
              
              void RecoveryProcessLoader::run() {
              	QTimer timer;
              	QEventLoop loop;
              	QEventLoop *loopPtr = &loop;
              	QList<QMetaObject::Connection> connections;
              
              	connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=](){
              		emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
              		loopPtr->exit(EXIT_BY_PING);
              		});
              
              	connections << connect(&timer, &QTimer::timeout, [=]() {
              		loopPtr->exit(EXIT_BY_TIMER);
              	});
              
              	timer.start(10);
              	int ret = loopPtr->exec();
              	timer.stop();
              
              	foreach(auto conn, connections) {
              		disconnect(conn);
              	}
              
              	if (ret != EXIT_BY_PING) {
              		this->exit(EXIT_INCORRECTLY);
              
              		if (!this->isFinished()) {
              			this->wait();
              		}
              		emit Finished(false);
              		return;
              	}
              }
              

              I am using thread with signal because of on arrival of the datareceivSwitch signal, I wanted to start the loop on value of true. loop should be continue work until certain conditions.

              the loop should exit many condition like below.

              1. if the data is not receive.
              2. if datarecevSwitch signal does not send in proper order.
                Order: true false true false.
              3. datarecevSwitch get send false value.

              after getting guidance from you I try to remove the Qthread and Make this change.

              .h file

              class RecoveryProcessLoader : public QObject
              {
              	Q_OBJECT
              public:
              	static RecoveryProcessLoader* Instance();
              
              public:
              	 void RecordReceiveByte(const uint NumberOfReceiveByte);
              	 void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);
              	 
              signals :
              	void ProgressChanged(int);
              	void Finished(bool);
              	void Started();
              	void dataReceivePing();
              	
              public slots:
              	void dataReceiveingSwitch(bool);
              
              private:
              	RecoveryProcessLoader();
              	uint getPageSize(const HardwareModel_t);
              	volatile uint numberOfReceiveByte;
              	volatile uint totalNumberOfbyte;
              	bool previousSignalVal = false;
              	bool updateProgressBar();
              	bool dataNotReceive = false;
              };
              

              .cpp file funcations

              void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
              	
              	while ((dataRxSwitch) && (!previousSignalVal))
              	{
              		previousSignalVal = true;
              
              		auto updateSuccessFull = updateProgressBar();
              
              		if (!updateSuccessFull) {
              			dataNotReceive = true;
              			emit Finished(false);
              			break;
              		}
              	}
              
              	if ((!dataRxSwitch) && (previousSignalVal) && (!dataNotReceive)) {
              		previousSignalVal = false;
              		emit ProgressChanged(100);
              		emit Finished(true);
              	}
              }
              
              
              #define EXIT_BY_TIMER	1
              #define EXIT_BY_PING	0
              
              bool RecoveryProcessLoader::updateProgressBar() {
              	QTimer timer;
              	QEventLoop loop;
              	QEventLoop *loopPtr = &loop;
              	QList<QMetaObject::Connection> connections;
              
              	connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=](){
              		emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
              		loopPtr->exit(EXIT_BY_PING);
              		});
              
              	connections << connect(&timer, &QTimer::timeout, [=]() {
              		loopPtr->exit(EXIT_BY_TIMER);
              	});
              
              	timer.start(10);
              	int ret = loopPtr->exec();
              	timer.stop();
              
              	foreach(auto conn, connections) {
              		disconnect(conn);
              	}
              
              	if (ret != EXIT_BY_PING) {
              		
              		emit Finished(false);
              		return false;
              	}
              	return true;
              }
              

              it make software crash. if i will comment loopPtr->exit(EXIT_BY_PING); and loopPtr->exit(EXIT_BY_TIMER); line then it is work.

              jsulmJ 1 Reply Last reply
              0
              • Y Yash001

                @jsulm.
                I want two functionality should work parallel.

                1. Thread One (Main thread);
                  - Write the Data into File
                  - Remove the Widgets if the Data Reeving completed ( few button and Progress bar dialog)

                2. another thread need to update progress bar.

                before you advise about Qthread I wrote this code. funcanality is work perfect.

                .h file

                #pragma once
                
                #include <global_typedefs.h>
                #include <QThread>
                #include <qtimer.h>
                #include <qeventloop.h>
                
                #define EXIT_CORRECTLY 0
                #define EXIT_INCORRECTLY 1
                
                class RecoveryProcessLoader : public QThread
                {
                	Q_OBJECT
                public:
                	static RecoveryProcessLoader* Instance();
                
                public:
                	 void RecordReceiveByte(const uint NumberOfReceiveByte);
                	 void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);
                	 
                signals :
                	void ProgressChanged(int);
                	void Finished(bool);
                	void Started();
                	void dataReceivePing();
                	
                public slots:
                	void dataReceiveingSwitch(bool);
                
                private:
                	RecoveryProcessLoader();
                	uint getPageSize(const HardwareModel_t);
                	volatile uint numberOfReceiveByte;
                	volatile uint totalNumberOfbyte;
                	bool previousSignalVal = false;
                	void run();
                };
                

                .cpp file

                #include "RecoveryLoader.h"
                
                
                RecoveryProcessLoader* RecoveryProcessLoader::Instance() {
                	static RecoveryProcessLoader * ret = 0 ;
                	if (0 == ret) {
                		ret = new RecoveryProcessLoader;
                	}
                	return ret;
                }
                
                RecoveryProcessLoader::RecoveryProcessLoader(){
                	//this->moveToThread(this);
                }
                
                uint RecoveryProcessLoader::getPageSize(const HardwareModel_t HWversion) {
                
                
                	return pageSizeOfFlash;
                }
                
                
                void RecoveryProcessLoader::calculateTotalBytes(const HardwareModel_t HWversion,const uint32_t numPagesUsed) {
                	numberOfReceiveByte = 0;
                	auto pageSize = getPageSize(HWversion);
                	totalNumberOfbyte = pageSize * 1;
                	return;
                	totalNumberOfbyte = pageSize * numPagesUsed;
                }
                
                void RecoveryProcessLoader::RecordReceiveByte(const uint numberOfByte) {
                	numberOfReceiveByte += numberOfByte;
                }
                
                void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
                	
                	if (dataRxSwitch && (!previousSignalVal)) {
                		
                		previousSignalVal = true;
                
                		emit ProgressChanged(0);
                		emit Started();
                		this->start();
                	}
                	else if ((!dataRxSwitch) &&(previousSignalVal)){
                		previousSignalVal = false;
                		
                		this->exit(EXIT_CORRECTLY);
                		if (!this->isFinished()) {
                			this->wait();
                		}
                
                		emit ProgressChanged(100);
                		emit Finished(true);
                		
                	}
                	else {
                		NULL;
                	}
                }
                
                // This Thread may through wrong value for Finished signal if the dataReceiveingSwitch signal does not received in correct order.
                #define EXIT_BY_TIMER	1
                #define EXIT_BY_PING	0
                
                void RecoveryProcessLoader::run() {
                	QTimer timer;
                	QEventLoop loop;
                	QEventLoop *loopPtr = &loop;
                	QList<QMetaObject::Connection> connections;
                
                	connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=](){
                		emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
                		loopPtr->exit(EXIT_BY_PING);
                		});
                
                	connections << connect(&timer, &QTimer::timeout, [=]() {
                		loopPtr->exit(EXIT_BY_TIMER);
                	});
                
                	timer.start(10);
                	int ret = loopPtr->exec();
                	timer.stop();
                
                	foreach(auto conn, connections) {
                		disconnect(conn);
                	}
                
                	if (ret != EXIT_BY_PING) {
                		this->exit(EXIT_INCORRECTLY);
                
                		if (!this->isFinished()) {
                			this->wait();
                		}
                		emit Finished(false);
                		return;
                	}
                }
                

                I am using thread with signal because of on arrival of the datareceivSwitch signal, I wanted to start the loop on value of true. loop should be continue work until certain conditions.

                the loop should exit many condition like below.

                1. if the data is not receive.
                2. if datarecevSwitch signal does not send in proper order.
                  Order: true false true false.
                3. datarecevSwitch get send false value.

                after getting guidance from you I try to remove the Qthread and Make this change.

                .h file

                class RecoveryProcessLoader : public QObject
                {
                	Q_OBJECT
                public:
                	static RecoveryProcessLoader* Instance();
                
                public:
                	 void RecordReceiveByte(const uint NumberOfReceiveByte);
                	 void calculateTotalBytes(const HardwareModel_t HWversion, const uint32_t numPagesUsed);
                	 
                signals :
                	void ProgressChanged(int);
                	void Finished(bool);
                	void Started();
                	void dataReceivePing();
                	
                public slots:
                	void dataReceiveingSwitch(bool);
                
                private:
                	RecoveryProcessLoader();
                	uint getPageSize(const HardwareModel_t);
                	volatile uint numberOfReceiveByte;
                	volatile uint totalNumberOfbyte;
                	bool previousSignalVal = false;
                	bool updateProgressBar();
                	bool dataNotReceive = false;
                };
                

                .cpp file funcations

                void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {
                	
                	while ((dataRxSwitch) && (!previousSignalVal))
                	{
                		previousSignalVal = true;
                
                		auto updateSuccessFull = updateProgressBar();
                
                		if (!updateSuccessFull) {
                			dataNotReceive = true;
                			emit Finished(false);
                			break;
                		}
                	}
                
                	if ((!dataRxSwitch) && (previousSignalVal) && (!dataNotReceive)) {
                		previousSignalVal = false;
                		emit ProgressChanged(100);
                		emit Finished(true);
                	}
                }
                
                
                #define EXIT_BY_TIMER	1
                #define EXIT_BY_PING	0
                
                bool RecoveryProcessLoader::updateProgressBar() {
                	QTimer timer;
                	QEventLoop loop;
                	QEventLoop *loopPtr = &loop;
                	QList<QMetaObject::Connection> connections;
                
                	connections << connect(this, &RecoveryProcessLoader::dataReceivePing, [=](){
                		emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
                		loopPtr->exit(EXIT_BY_PING);
                		});
                
                	connections << connect(&timer, &QTimer::timeout, [=]() {
                		loopPtr->exit(EXIT_BY_TIMER);
                	});
                
                	timer.start(10);
                	int ret = loopPtr->exec();
                	timer.stop();
                
                	foreach(auto conn, connections) {
                		disconnect(conn);
                	}
                
                	if (ret != EXIT_BY_PING) {
                		
                		emit Finished(false);
                		return false;
                	}
                	return true;
                }
                

                it make software crash. if i will comment loopPtr->exit(EXIT_BY_PING); and loopPtr->exit(EXIT_BY_TIMER); line then it is work.

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

                @Yash001 said in What is good way to update the Progressbar value?:

                connections << connect(this, &RecoveryProcessLoader::dataReceivePing, ={
                emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
                loopPtr->exit(EXIT_BY_PING);
                });

                connections << connect(&timer, &QTimer::timeout, = {
                loopPtr->exit(EXIT_BY_TIMER);

                No wonder this crashes!
                You pass pointer to a local variable to a lambda. If then the signal is emitted after updateProgressBar() finished then the lambda will try to dereference a dangling pointer. Move the loop variable to the class (make it class member). But I still not see a need for a thread to update the progress bar - updating a progress bar is not an expensive operation and really does not need a thread.

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

                Y 1 Reply Last reply
                2
                • jsulmJ jsulm

                  @Yash001 said in What is good way to update the Progressbar value?:

                  connections << connect(this, &RecoveryProcessLoader::dataReceivePing, ={
                  emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
                  loopPtr->exit(EXIT_BY_PING);
                  });

                  connections << connect(&timer, &QTimer::timeout, = {
                  loopPtr->exit(EXIT_BY_TIMER);

                  No wonder this crashes!
                  You pass pointer to a local variable to a lambda. If then the signal is emitted after updateProgressBar() finished then the lambda will try to dereference a dangling pointer. Move the loop variable to the class (make it class member). But I still not see a need for a thread to update the progress bar - updating a progress bar is not an expensive operation and really does not need a thread.

                  Y Offline
                  Y Offline
                  Yash001
                  wrote on last edited by Yash001
                  #8

                  @jsulm to handle this condition, I use the

                  QList<QMetaObject::Connection> connections;
                  

                  and

                  foreach(auto conn, connections) {
                  		disconnect(conn);
                  	}
                  

                  I am disconnecting all local signal in side the updateProgressBar().

                  am I doing any wrong for disconnecting signals?

                  another things is timer is local object. if I will comment only

                  loopPtr->exit(EXIT_BY_PING);
                  

                  then also i am getting same issue.

                  jsulmJ 1 Reply Last reply
                  0
                  • Y Yash001

                    @jsulm to handle this condition, I use the

                    QList<QMetaObject::Connection> connections;
                    

                    and

                    foreach(auto conn, connections) {
                    		disconnect(conn);
                    	}
                    

                    I am disconnecting all local signal in side the updateProgressBar().

                    am I doing any wrong for disconnecting signals?

                    another things is timer is local object. if I will comment only

                    loopPtr->exit(EXIT_BY_PING);
                    

                    then also i am getting same issue.

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

                    @Yash001 Then you should check the stack trace when your app crashes...

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

                    Y 1 Reply Last reply
                    2
                    • jsulmJ jsulm

                      @Yash001 Then you should check the stack trace when your app crashes...

                      Y Offline
                      Y Offline
                      Yash001
                      wrote on last edited by
                      #10

                      @jsulm Thank you for giving me direction.

                      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