QThread中的QSerialPort运行bytesAvailable为零

时间:2015-11-16 21:29:31

标签: multithreading qt serial-port

有一个简单的Qt应用程序。 Gui线程,创建它创建的Dev线程(在其run()中)读取线程。 Dev和Read线程是我从QThread继承的类。 Read线程应该连续从COM端口读取数据。以下是读取运行的近似视图。

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);
    }
  }
}

要启动它,我会在GUI中发出传递给Dev的信号,然后传递给下面的读取插槽:

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();
}
}

这很有效。但是,如果我创建并设置并打开串口运行方法,那么端口是打开的,但bytesAvailable()总是为零?为什么有可能?

高兴地感谢你。

1 个答案:

答案 0 :(得分:0)

我同意Orest Hera,因为你正在使用"非推荐"实现线程的方式。

您正在为线程对象使用继承。

了解QThreads的工作原理非常重要。使用QThreads的一般程序是:

  • 让对象进入线程,不指定父级
  • 制作主题
  • 使用obj-> moveToThread(thread)
  • 将对象移动到thead中
  • 将信号连接到对象中的插槽,该插槽将实例化对象成员(如果需要)
  • 启动主题:thread-> start()

例如:

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();

所以你的对象仍然可以拥有" run()"功能,但它不会超载任何东西。 你的run()函数也不一定是"永远"循环,它只是一个初始化函数(创建串口或其他)。然后为其他事件添加其他插槽,例如您可以将QSerialPort :: readyRead()连接到您的"传入数据槽"处理程序来处理从串口接收的任何数据....等等。

我认为这将解决您的问题。很难准确说明为什么你的串口不能在你的重载" Run()"函数,因为我无法看到你如何调用/创建线程(即你的代码的其余部分)或DO_EXEC初始化的地方等...这里可能有一些事件或线程所有权问题的排序。

注意:我并不是说你不能继承线程类,但是如果你这样做就是你创建自己的自定义线程类(做线程的东西),而不是创建一个其他的类线程实用程序和其他东西的混合。如果你对为什么/如何等等感兴趣,那么在这里(在SO上)和在qt论坛上有相当多的相关信息......:)