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. can we use the Qtimer & QeventLoop in different thread?
QtWS25 Last Chance

can we use the Qtimer & QeventLoop in different thread?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qeventloopqtimerqthread
8 Posts 3 Posters 4.9k 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

    void RecoveryProcessLoader::dataReceiveingSwitch(bool dataRxSwitch) {

    if (dataRxSwitch && (!previousSignalVal)) {
    	
    	previousSignalVal = true;
    	
    	emit Started();
    	emit ProgressChanged(0);
    	this->moveToThread(&progressBarThread);
    	progressBarThread.start();
    	
    }
    else if ((!dataRxSwitch) &&(previousSignalVal)){
    	previousSignalVal = false;
    	
    	progressBarThread.exit(EXIT_CORRECTLY);
    	if (!progressBarThread.isFinished()) {
    		progressBarThread.wait();
    	}
    	
    	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(1000);
    int ret = loopPtr->exec();
    timer.stop();
    
    foreach(auto conn, connections) {
    	disconnect(conn);
    }
    
    if (ret != EXIT_BY_PING) {
    	progressBarThread.quit();
    
    	if (!progressBarThread.isFinished()) {
    		progressBarThread.wait();
    	}
    
    	emit Finished(false);
    	return;
    }
    

    }

    setProgressbarValue is start to execute on started siganl of progressBarThread thread. here int ret = loopPtr->exec(); return -1. what is wrong with timeout signal of timer. I am not getting time out signal and dataReceivePing signal.

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Please put your code between code tags. It is very hard to read in it's current form.

      this->moveToThread(&progressBarThread);
      progressBarThread.start(); 
      

      Moving current object to another thread is not a good idea. Especially when your thread is a child/ local variable of that same object.

      Where is progressBarThread defined?

      void RecoveryProcessLoader::setProgressbarValue() {
      

      Is this method run in your new thread or your main thread?

      (Z(:^

      Y 2 Replies Last reply
      1
      • sierdzioS sierdzio

        Please put your code between code tags. It is very hard to read in it's current form.

        this->moveToThread(&progressBarThread);
        progressBarThread.start(); 
        

        Moving current object to another thread is not a good idea. Especially when your thread is a child/ local variable of that same object.

        Where is progressBarThread defined?

        void RecoveryProcessLoader::setProgressbarValue() {
        

        Is this method run in your new thread or your main thread?

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

        @sierdzio

        //********* 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();
        	void dataReceivePing();
        	
        
        public slots:
        	void dataReceiveingSwitch(bool);
        	void setProgressbarValue();
        private:
        	RecoveryProcessLoader();
        	~RecoveryProcessLoader();
        	uint getPageSize(const HardwareModel_t);
        	volatile uint numberOfReceiveByte;
        	volatile uint totalNumberOfbyte;
        	QThread progressBarThread;
        
        	bool previousSignalVal = false;
        };
        
        

        //***********************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,Qt::DirectConnection);
        	
        }
        
        RecoveryProcessLoader::~RecoveryProcessLoader() {
        	QObject::disconnect(&progressBarThread, &QThread::started, this, &RecoveryProcessLoader::setProgressbarValue);
        }
        
        uint RecoveryProcessLoader:: getPageSize(const HardwareModel_t HWversion) {
        
        	auto pageSizeOfFlash = 512;
        	
        	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 Started();
        		emit ProgressChanged(0);
        		this->moveToThread(&progressBarThread);
        		progressBarThread.start();
        		
        	}
        	else if ((!dataRxSwitch) &&(previousSignalVal)){
        		previousSignalVal = false;
        		
        		progressBarThread.exit(EXIT_CORRECTLY);
        		if (!progressBarThread.isFinished()) {
        			progressBarThread.wait();
        		}
        		
        		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;
        
        	QObject::connect(this, &RecoveryProcessLoader::dataReceivePing, [=]() {
        		emit ProgressChanged((numberOfReceiveByte * 100) / totalNumberOfbyte);
        		loopPtr->exit(EXIT_BY_PING);
        	});
        	
        	QObject::connect(&timer, &QTimer::timeout, [=]() {
        		loopPtr->exit(EXIT_BY_TIMER);
        	});
        
        	timer.start(1000);
        	int ret = loopPtr->exec();
        	timer.stop();
        
        	foreach(auto conn, connections) {
        		disconnect(conn);
        	}
        
        	if (ret != EXIT_BY_PING) {
        		progressBarThread.quit();
        
        		if (!progressBarThread.isFinished()) {
        			progressBarThread.wait();
        		}
        
        		emit Finished(false);
        		return;
        	}
        }
        

        Thank you @sierdzio for you advise. Here i put my full code. I am writing this code for updating the Progress Bar Value.

        1 Reply Last reply
        0
        • sierdzioS sierdzio

          Please put your code between code tags. It is very hard to read in it's current form.

          this->moveToThread(&progressBarThread);
          progressBarThread.start(); 
          

          Moving current object to another thread is not a good idea. Especially when your thread is a child/ local variable of that same object.

          Where is progressBarThread defined?

          void RecoveryProcessLoader::setProgressbarValue() {
          

          Is this method run in your new thread or your main thread?

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

          @sierdzio I am Trying to create the separate thread which is continuously update the progrss bar on arrival of the data.

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

            @SGaist what change do i need to make sir?? could you please guid me??

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

              This Code Work fine but i don't know the different. any one please give advise, what was the mistake, I was doing wrong if class derive from QObject.

              if I will move the object into working thread then also it is working good.
              but I don't know, why it was not working if I derive the class from the Object and use the Qthread Object.

              what is different in between two things?

              Just for note: my dataReceiveingSwitch signal is working into main thread in both case.

              /********************RecoveryLoader.h ********************/

              #pragma once
              
              #include <global_typedefs.h>
              #include <QThread>
              #include <qtimer.h>
              #include <qeventloop.h>
              #include "qapplication.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();
              };
              
              

              /****RecoveryLoader.cpp/

              #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;
              	}
              }
              
              1 Reply Last reply
              0
              • BuckwheatB Offline
                BuckwheatB Offline
                Buckwheat
                wrote on last edited by
                #7

                Hi @Yahoo!

                Please read Maya's blog on threading in Qt5: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ for the best explanation on threading for Qt that is not in the docs.

                Using the worker thread based off QObject will allow your timer to work from the thread without having to touch the event queue. I have found I NEVER want to override run anymore. My worker object sets up the timer in the start slot and emits a signal to the client while running. This will tru;y make you app event driven and waiting or "processing" the event queue is rendered unnecessary.

                I have several posts about this and it really is a nice way to work with the objects. For functional style threads, I use QFuture.

                Dave Fileccia

                Y 1 Reply Last reply
                3
                • BuckwheatB Buckwheat

                  Hi @Yahoo!

                  Please read Maya's blog on threading in Qt5: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ for the best explanation on threading for Qt that is not in the docs.

                  Using the worker thread based off QObject will allow your timer to work from the thread without having to touch the event queue. I have found I NEVER want to override run anymore. My worker object sets up the timer in the start slot and emits a signal to the client while running. This will tru;y make you app event driven and waiting or "processing" the event queue is rendered unnecessary.

                  I have several posts about this and it really is a nice way to work with the objects. For functional style threads, I use QFuture.

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

                  @Buckwheat Thank you documents link. I will read it and trying to make change in my code. thank you @Buckwheat .

                  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