Using QThread to try and set a clock that writes current time to a text edit box.
-
You should be able to do this with a QTimer as opposed to a QThread. This is probably unnecessary to go this extreme.
In your example the 'run' method from the thread exits immediately after reading the time.
void currentTimeThread::run() { QTime time = QTime::currentTime(); QString currentTime = time.toString("hh:mm:ss:ms"); emit timeChanged(currentTime); } // this version will run forever and send a signal every second with the current time. void currentTimeThread::run() { QTime time ; QString currentTime; do { time = QTime::currentTime(); currentTime = time.toString("hh:mm:ss:ms"); emit timeChanged(currentTime); this->msleep(1000); // sleep for 1 second }while (true); }
You should look into getting the time from your GUI thread when processing the data. Maybe using the tread for only reading the temperatures perhaps?
When working with a thread you should also connect the signals 'started()' and 'finished()' to monitor what it is doing. When you close the program you should also consider a way to shut down the thread if it is still running.
-
Thanks I will try that approach. I had used QTime before and it got all the times posted but would not do it in real time so tried QThread.
-
@Rondog Where do I connect the started() and finsihed() signals at? Looking in the documentation it says
void currentTimeThread::started()
but not where it goes, is it just in the .h file for the thread? -
Hi,
Currently, a thread looks like overkill for what you want to do. Using a QTimer (not QTime, QTimer) is enough. You should just write a class that does this. If you really need a thread then, use the worker object paradigm (described in QThread's documentation)
-
@SGaist I have also tried using QTimer and that will get the time in the text edit box, but only after the rest of the code has ran so it is not populating in real time. My code is.
void noheatmode::displayCurrentTime() { //Start timers to recursively get current time QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT()); //delay set to space out time readings, can be adjusted timer->start(750); //Gets the time QTime time = QTime::currentTime(); //Converts to string with chosen format QString sTime = time.toString("hh:mm:ss:ms"); //displays current time in text edit box ui->tempTimeNoHeatMode->append(sTime); } //Set loop to run while flow time is not 0 while(flowTime > 0) { displayCurrentTime(); //set zero pin to be high while flowtime is more than 0 digitalWrite(0,1); flowTime--; // set second pin LED to flash according to dutyCycle digitalWrite(2,1); delay(onTime); digitalWrite(2,0); delay(offTime); } //turn zero pin low after flow time reaches 0 digitalWrite(0,0); }
-
Because you are still using a loop that is blocking the GUI thread
-
@cdbean04 said:
//Set loop to run while flow time is not 0 while(flowTime > 0) { ... }
Like @Sgaist said, you must not have a while loop that runs for a long time. This makes all of your GUI freeze.
When your GUI is frozen:
- Your displays will not update (that's why your time display doesn't update)
- You can't click on any buttons.
- You can't type any text.
-
Would you recommend I just use a different or shorter loop. What the loop is doing, in case I have not been clear, is turning on an led light that represents a valve opening to release a flow of water. A second led, which represents a pulse to a flow through heater, has to flash for a certain amount of milliseconds per second that the water flow led light is on. While all that is happening I also need to check the temperature of the water, and possible count pulses from a separate flow meter. To achieve all this should I can my logic and adjust my looping, or should I use Qthread? In your opinion of course.
-
You should rather take a look at the State Machine Framework. That will allow you to better handle your system.
-
@SGaist After looking through the State Machine Framework, it looks like I would have to do nested states to get everything to run independently, but at the same time. Is this correct or am thinking to complex?
-
It depends on what parts you want to model with the state machine.
-
My thoughts were to have flowTime (which is currently in the while loop, be a a state. And have the time stamp, temperature reading, and any other elements that need to run at the same time as nested state machines in the flowTime state.
Here is flowTime now// set zero pin LED to stay on for flowTime while(flowTime > 0) { digitalWrite(0,1); flowTime--; // set second pin LED to flash according to dutyCycle digitalWrite(2,1); delay(onTime); digitalWrite(2,0); delay(offTime); }
-
Aren't all these parts independent ?