问题
Have a simple Qt app. Gui thread, creates Dev thread it creates (in its run()) Read thread. Dev and Read threads are my classes inherited from QThread. The Read thread should read data from COM port continuously. An approximate view of Read run is following.
read::run()
{
sp2->clear();
while (DO_EXEC)
{
if (DO_WRITE)
{
// write data to port
}
usleep(500);
ba = sp2->bytesAvailable();
if (ba > 0)
{
int a = sp2->read(&BUF[BUF_END], ba);
// process data
emit sgnl(sendeddata);
}
}
}
To start it I emit signal in GUI that is passed to Dev at it is passed to the following read slot:
read::slot_readStart()
{
// some stuff
if (doStart && !isRunning())
{
sp2 = new QSerialPort(this);
sp2->setPortName("COM3");
sp2->setBaudRate(256000);
sp2->setDataBits(QSerialPort::Data8);
sp2->setStopBits(QSerialPort::OneStop);
sp2->setParity(QSerialPort::NoParity);
sp2->setFlowControl(QSerialPort::NoFlowControl);
sp2->setReadBufferSize(5000);
bool isOpen = sp2->open(QIODevice::ReadWrite);
DO_EXEC = true;
start();
}
}
This works. But, if I place creating and setup and opening serial port to run method, then the port is open, but the bytesAvailable() are always zero? Why it is possible?
Thank you in adcance.
回答1:
I agree with Orest Hera, in that you are using a "non recommended" way of implementing threads.
You are using inheritance for your thread object.
It is important to understand how QThreads work. The general procedure to using the QThreads is:
- Make Object to go into thread, assign no parent
- Make thread
- Move object into thead using obj->moveToThread(thread)
- Connect a signal to a slot in the object that will instatiate the object members (if required)
- Start the thread: thread->start()
For example:
MyObj *myObj = new MyObj(0); // 0 = no parent if your object inherits QObject
QThread* thread = new QThread;
myObj->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), myObj, SLOT(run()));
thread->start();
So your object can still have its "run()" function, but it won't be overloading anything. Also your run() function does not need to be a "forever" loop, it is simply an initialization function (create the serial port or whatever). Then you add other slots for other events, e.g. you can connect the QSerialPort::readyRead() to your "incoming data slot" handler to handle any data received from the serial port.... and so on.
I think this will solve your issues. It is difficult to tell exactly why your serial port does not work in your overloaded "Run()" function because I can't see how you are calling /creating the thread (i.e. the rest of your code) or where DO_EXEC is initialized etc... There is probably some ordering of events or thread ownership issue here.
Note: I am not saying you can't inherit thread class, but if you do that it is so that you create your own custom thread class (to do thread stuff), but not some other class to create a hybrid of thread utility and other stuff. There is a fair amount of information relating to this here (on SO) and on the qt forum if you are interested in the why/how etc... :)
来源:https://stackoverflow.com/questions/33744997/qserialport-in-qthread-run-bytesavailable-is-zero