QSerialPort in QThread run bytesAvailable is zero

心不动则不痛 提交于 2020-01-16 18:18:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!