本文介绍了QThread运行字节中的QSerialPort可用为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

拥有一个简单的Qt应用. Gui线程,创建它创建的Dev线程(在其run()中)Read线程. Dev和Read线程是我从QThread继承的类.读取线程应连续从COM端口读取数据.下面是读取运行"的大致视图.

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

要启动它,我会在GUI中发出信号,然后将其传递到Dev并传递到以下读取插槽:

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

这有效.但是,如果我将创建,设置和打开串行端口作为运行方法,那么该端口是开放的,但是bytesAvailable()始终为零吗?为什么有可能?

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?

非常感谢您.

推荐答案

我同意Orest Hera的观点,因为您使用的是不推荐"的实现线程的方式.

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.

重要的是要了解QThreads的工作方式.使用QThreads的一般过程是:

It is important to understand how QThreads work. The general procedure to using the QThreads is:

  • 使对象进入线程,不分配父对象
  • 创建线程
  • 使用obj-> moveToThread(thread)将对象移动到广告中
  • 将信号连接到对象中的插槽,该插槽将使对象成员不真实(如果需要)
  • 启动线程: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()连接到传入数据插槽"处理程序,以处理从串行端口接收到的所有数据...等等.

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.

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

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.

注意:我并不是说您不能继承线程类,但是如果这样做,您可以创建自己的自定义线程类(以处理线程),但不能创建其他类来创建线程的混合体.线程实用程序和其他东西.如果您对原因/方式等感兴趣,可以在此处(在SO上)和qt论坛上找到与之相关的大量信息.:)

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... :)

这篇关于QThread运行字节中的QSerialPort可用为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 16:39