QSerialPort in another thread. Doesn't report errors...
-
Hi all. I am developing a GUI which will communicate to some hardware over a virtual serial port (USB to serial cable). I want to detect when the cable is disconnected. I have loaded the terminal example in QT creator and when I open the virtual serial port and then unplug it from the computer, an error is triggered, which is the correct behavior. I want my program to do the same thing.
The thing is, I want to make a class that runs in a separate thread which contains a QSerialPort object and handles communication using this QSerialPort object. I want to connect the error signal from the QSerialPort class to my own error handler in my new class. The problem I have is that the error signal is never triggered with the right signal (QSerialPort::ResourceError)! In the terminal example program, this signal is correctly generated.
I think this is some sort of thread affinity issue. If I instead make the QSerialPort object a member of the mainwindow class and then connect the serial port object's error signal to a member slot of mainwindow, everything works A-OK when I rip the USB cable from my computer. Any ideas?
-
Also, this is my first time using QThreads. My mainwindow constructor does the following to set up the SSACom2 object (the object that has a Qserialport and handles connection stuff at a higher level): cThread is member of my MainWindow class.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cThread = new QThread(this);scom = new SSAComm2(NULL); scom->doSetup(cThread); scom->moveToThread(cThread); cThread->start();
}
-
Hi,
Can you show us the code inside SSAComm2::doSetup()?
-
Yes. ssacomm2.cpp:
#include "ssacomm2.h"
#include <QDebug>SSAComm2::SSAComm2(QObject *parent) : QObject(parent)
{}
SSAComm2::~SSAComm2()
{}
void SSAComm2::doSetup(QThread *cThread)
{
connect(cThread, SIGNAL(started()), this, SLOT(doWork()));
thisThread = cThread;
port = new QSerialPort(this);
port->setPortName("COM3");
port->open(QIODevice::ReadWrite);
connect(port, SIGNAL(error(QSerialPort::SerialPortError)), this,
SLOT(handleError(QSerialPort::SerialPortError)));
qDebug() << "SSA Comm2 starting!";
}void SSAComm2::doWork()
{
while(1);return;
}
void SSAComm2::handleError(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError) {
qDebug() << "Error! Unplugged Cable!!!"; //This never executes when I unplug the USB cable!!!!
}
} -
Hi,
You have 2 problems:
@zeneslev said:
void SSAComm2::doSetup(QThread *cThread) { ... port = new QSerialPort(this); port->setPortName("COM3"); port->open(QIODevice::ReadWrite); ... }
1st problem: You created and opened the serial port in the main thread.
You must call the QSerialPort constructor and open() in your worker thread.
@zeneslev said:
void SSAComm2::doWork() { while(1); return; }
2nd problem: You have an infinite loop in doWork().
When a thread is running an infinite loop, it cannot cannot process any signals because the infinite loop blocks the event loop.
-