Horse sense is the thing that keeps horses from betting on people. --W.C. Fields
Ask Smart Questions
Qt Code:
void Thread::run() { exec(); }To copy to clipboard, switch view to plain text mode
u can do all doAction() work inside run() itself ...
Qt Code:
void ::run() { while(stopped){ here i write some data to port and then get some data emit update(some data); sleep(1); } } void Thread::stop() { stopped = true; wait(); }To copy to clipboard, switch view to plain text mode
and no need to call QThread::exec();(protected) seperately as QApp->exec(); is enough
"Behind every great fortune lies a crime" - Balzac
Ok, i've rewrite it, so at the moment it looks like this
Qt Code:
/* Thread.h */ #include <QThread> { Q_OBJECT public: Object(); protected: signals: void update(int); private: int timerId; } { Q_OBJECT public: Thread(); void run(); private: Object* object; };To copy to clipboard, switch view to plain text modeAs i understood, you advised me to create an object inside QThread::run() function and then to use a timer for this object. Unfortunately, GUI is steel freezing when this object is trying to read from port. Maybe, i've missed something?Qt Code:
/* Thread.cpp */ #include "Thread.h" Thread::Thread() { } void Thread::run() { object = new Object(); exec(); } Object::Object() { timerId = startTimer(1000); } Object::~Object() { killTimer(timerId); } here i write some data to port and then get some data emit update(some data); }To copy to clipboard, switch view to plain text mode
Your code works fine for me (with a sleep call in timerEvent). The update slot will run in the GUI thread, are you doing anything that could cause a freeze in that function?
No, inside timerEvent function i just write data to COM port and then read from port. The only thing that is slow enough is reading data from port, when there is no data to read. In this case i do up to 10 attempts to read and then return either a piece of data or error. But this function is performed within the separate thread, so it shouldn't influence the GUI thread. Update slot in GUI displays the value from timerEvent function in QLCDNumber.
Anyway, i'll rewrite my code step by step to find what causes GUI to freeze.
Thank you all, i really appreciate your help, since this is my first experience of working with threads.
Why you check the serial port with a timer instead of doing it directly in the run() of the thread?
I use QextSerialPort and I check the available data in a thread like this:
Qt Code:
{ Q_OBJECT public: ReceiveThread(QextSerialPort *adrPort); ~ReceiveThread(); void stopReceiving(); protected: void run(); signals: private: QextSerialPort *d_port; //!< Reference to the serial port to monitor QMutex mutex; //!< Mutex lock bool stopped; //!< Specify if the thread is running or not (it is needed to stop the thread) }; ReceiveThread::ReceiveThread(QextSerialPort *adrPort) : d_port(adrPort), stopped(false) { } ReceiveThread::~ReceiveThread() { if (isRunning()) { stopReceiving(); wait(); } } void ReceiveThread::stopReceiving() { stopped = true; } //! The Receive Thread Loop void ReceiveThread::run() { QByteArray data; int bytesAvailable; data.reserve(MAX_BUFFER_SIZE); while(!stopped) { mutex.lock(); bytesAvailable = d_port->bytesAvailable(); if (bytesAvailable > 0) data.append(d_port->read((bytesAvailable<MAX_BUFFER_SIZE)? bytesAvailable: MAX_BUFFER_SIZE)); mutex.unlock(); if (bytesAvailable) qDebug() << tr("ReceiveThread: %1").arg(bytesAvailable); if (!data.isEmpty()) { emit dataReceived(data); qDebug() << tr("ReceiveThread: Emitted Data Received"); data.clear(); } msleep(RECEIVE_THREAD_SLEEP_TIME); } }To copy to clipboard, switch view to plain text mode
To use this class you only nead to istantiete the class and call the run() method to start the monitoring of the serial port.
To stop the monitoring you must call the stopReceiving() method.
The data received is emitted with the signal dataReceived(const QByteArray &), so you have to connect this with a slot to manage the data received.
WARNING
This class does not perform any check on the QextSerialPort provided, you have to perform these check before starting the Receive Thread. Also you have to stop the Receive Thread before close the QextSerialPort.
So, instead to instantiate the Thread directly in the Main you have to instantiate it in your MainWindow after create and open the serialport.
Bookmarks