c++ - 如何在单独的线程上设置 QSerialPort?

标签 c++ qt qthread qtcore qtserialport

按照官方文档,我正在尝试这样做:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QThread *thread = new QThread;    
    Worker *worker= new Worker();

    worker->moveToThread(thread);

    //init connections

    thread->start();
}

worker 构造函数:

Worker::Worker(QObject *parent) :
    QObject(parent)
{
    serial = new QSerialPort(this);  //passing the parent, which should be the current thread      
}

没有编译错误但是当我执行它时抛出这个:

QObject: Cannot create children for a parent that is in a different thread. 
(Parent is QSerialPort(0x11bd1148), parent's thread is QThread(0x11bd2ef8), current thread is QThread(0x3e47b8)

也就是说,它告诉我 serial 的父线程是主线程,而不是我创建的线程。

如果我不在构造函数中而是在主进程中实例化 serial,结果相同,这是在我们调用 thread->start() 之后触发的:

Worker::Worker(QObject *parent) :
    QObject(parent)
{             
}

Worker::doWork()
{
    if(!serial)
        serial= new QSerialPort(this); 

    //...
}

我错过了什么?


以发送函数为例(一个slot):

void Worker::send(const QByteArray &data)
{
    serial->write(data);
    if( serial->waitForBytesWritten(TIMEOUT) )
        qDebug() << "sent: " << data;
}

最佳答案

简而言之,像这样使用 QtSerialPort 模块是个坏主意。

我们基于 QIODevice 设计了这个模块,它已经为您的 GUI 应用程序提供了非阻塞机制以使用 QSerialPort 类。

您应该查看以下信号:

void QIODevice::bytesWritten(qint64 bytes) [signal]

This signal is emitted every time a payload of data has been written to the device. The bytes argument is set to the number of bytes that were written in this payload. bytesWritten() is not emitted recursively; if you reenter the event loop or call waitForBytesWritten() inside a slot connected to the bytesWritten() signal, the signal will not be reemitted (although waitForBytesWritten() may still return true).

和...

void QIODevice::readyRead() [signal]

This signal is emitted once every time new data is available for reading from the device. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.

readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).

Note for developers implementing classes derived from QIODevice: you should always emit readyRead() when new data has arrived (do not emit it only because there's data still to be read in your buffers). Do not emit readyRead() in other conditions.

我写了两个通过命令行执行此操作的示例,您可以在此处找到它们:

Command Line Writer Async Example

Command Line Reader Sync Example

关于c++ - 如何在单独的线程上设置 QSerialPort?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23559610/

相关文章:

python - 如何在 python 中终止 qthread

c++ - QObjects 移入 QThreads 后信号不再工作

C++错误error LNK2019 : unresolved external symbol,语法错误?

c++ - vector<vector<int>> 上的 push_back 问题

c++类前向声明​​和不完整类型的无效使用

Qt,如何立即暂停QThread

c++ - 如果不是直接从代码中使用,为什么要包含 <string>?

c++ - 在 iOS 项目中将 c++ 与 objective-c 集成

linux - 在 Linux 上不使用 Qt 运行我的应用程序

c++ - 将 CfbsBitmap 格式转换为 JPG