Thread that read from QSerialPort
-
Hi,
the problem is that i'm developing an application that communicate with an external interface with the serial port so it continuosly communicate with it while the GUI need to be responsive and accept user input/show values etc...
So i want to separate read/write from serial port AND the GUI
What you suggest to do?
-
Reading the documentation i found that maybe i have to substitute
@while(!end)
{
sleep(1)
}@whit @exec()@
that enters the event loop and waits until exit() is calle
Is it correct?
Thanks
-
No it is not correct. You don't need a wait loop like that.
-
[quote author="rileo8" date="1383208867"]that enters the event loop and waits until exit() is calle
Is it correct?[/quote]Yes, it's correct :)
Next, read the "Thread Affinity" section of the "QObject documentation":http://doc-snapshot.qt-project.org/qt5-stable/qobject.html#thread-affinity -- it explains how to choose the thread to run your slots.
[quote author="t3685" date="1383215445"]No it is not correct. You don't need a wait loop like that.[/quote]rileo8 realized that after reading the documentation. That's why he asked if it's correct to replace the wait loop with exec().
-
Ok,
i'm understanding that i hadn;t understand qthreads before... :-)
The question is :i need a "worker" thread that read and write from a serial port so i can use this approach:
class Worker : public QObject
{
Q_OBJECT
private slots:
void onTimeout()
{
qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId();
}
};@class Thread : public QThread
{
Q_OBJECTprivate:
void run()
{
qDebug()<<"From work thread: "<<currentThreadId();
QTimer timer;
Worker worker;
connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout()));
timer.start(1000);exec(); }
};@
the problem is...if i need that the worker thread receive signals from the GUI what i have to do? Connect with signal&slot the GUI withe theThread class and then connect always with signals/slot the thread calls with the worker class?
-
To make things simple, you don't need to subclass QThread. Just have the timer in your worker:
@
class Worker : public QObject
{
Q_OBJECT
QTimer* timer;public:
Worker(QObject *parent = 0) : QObject(parent) {
// Worker must be parent of QTimer
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}public slots:
void startWorking() { timer->start(1000); }private slots:
void onTimeout() {...}
};
@@
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QThread thread;
Worker worker;QObject::connect(&thread, SIGNAL(started()), &worker, SLOT(startWorking())); worker.moveToThread(&thread); thread.start(); int returnValue = a.exec(); thread.wait(); return returnValue;
}
@You can connect signals and slots directly between your worker and your GUI.
-
Ok perfect,thanks to everybody for the help!
Now i better understand Qthreads... -
You're welcome.
Good luck with your project!
-
Hi, i'm stille here with another question..
now my code loooks like this:
@#include "mainwindow.h"
#include <QtGui/QApplication>
#include <QThread>#include "executer.h"
#include "checker.h"
#include "networker.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();Checker checker;
Networker networker;
Executer executer;QThread checkerThread;
QThread networkerThread;
QThread executerThread;QObject::connect(&executerThread,SIGNAL(started()),&executer,SLOT(Start()));
checker.moveToThread(&checkerThread);
networker.moveToThread(&networkerThread);
executer.moveToThread(&executerThread);checkerThread.start();
networkerThread.start();
executerThread.start();int returnValue=a.exec();
executerThread.wait();
return returnValue;
}
@i neew to share an object (of a custom Configuration type) between all trheads.
Is it coorect to declare it in the main, pass it to all htreads and also share a mutex so that every thread lock and unlock it?
Thanks
-
If it is not a QObject, then yes you can do that.
If it is a QObject, then you are not allowed to share it between threads. QObject is not thread-safe.
See this page for info on how to share data between threads: http://doc-snapshot.qt-project.org/qt5-stable/threads-synchronizing.html
-
[quote author="JKSH" date="1383215991"][quote author="rileo8" date="1383208867"]that enters the event loop and waits until exit() is calle
Is it correct?[/quote]Yes, it's correct :)
Next, read the "Thread Affinity" section of the "QObject documentation":http://doc-snapshot.qt-project.org/qt5-stable/qobject.html#thread-affinity -- it explains how to choose the thread to run your slots.
[quote author="t3685" date="1383215445"]No it is not correct. You don't need a wait loop like that.[/quote]rileo8 realized that after reading the documentation. That's why he asked if it's correct to replace the wait loop with exec().[/quote]
The QSerialPort class is asynchronous. You don't need threads to do this.
-
It is not a QObject, is a simple c++ custom class
-
[quote author="t3685" date="1383225223"]The QSerialPort class is asynchronous. You don't need threads to do this.[/quote]Yes, if I/O is slow enough, then no threads are needed. That's why I asked about the read/write rate.
-
Yes i understood this,
infact now i have:GUI thread
thread for operations on serialport 1
thread for operations on serialport 2
thread for network operationsNow i also added a custom Configuration class that is share d between threads with a shared QMutex to enable access to it
-
[quote author="JKSH" date="1383225543"][quote author="t3685" date="1383225223"]The QSerialPort class is asynchronous. You don't need threads to do this.[/quote]Yes, if I/O is slow enough, then no threads are needed. That's why I asked about the read/write rate.[/quote]
The write function returns immediately. The readyRead() signal is only emitted when data is available. I don't think it matters then what the Baud rate is.
-
[quote author="t3685" date="1383225815"]
The write function returns immediately. The readyRead() signal is only emitted when data is available. I don't think it matters then what the Baud rate is.[/quote]Sorry for being unclear; I meant the rate at which read() and write() need to be called (relative to other operations). An active thread will experience jitter, especially on a non-real-time OS. That raises the possibility of a buffer becoming empty. Depending on how the devices have been designed, an empty write buffer could kill the entire connection.t3685 has a very valid point though. rileo8, try running your workers in the main thread first using the asynchronous API, and see how your program performs. You might not need 3 extra threads.
-
Hi,
my point is that i need to accomplish different operations on 2 serial ports and also network operations so i think that putting all i t he gui can cause gui freezing...
-
Hi guys,
the main point to use QtSerialPort's objects in different thread - a bug with the stopping of I/O at moving window or expanding window. Of course, this problem only in Windows OS. :)
[quote]
GUI thread
thread for operations on serialport 1
thread for operations on serialport 2
thread for network operations
[/quote]
IMHO, it is better:
-
GUI thread
-
thread for operations on serialport 1, serialport 2, network
-