6

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

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

    worker->moveToThread(thread);

    //init connections

    thread->start();
}

工人构造函数:

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主线程而不是我创建的线程作为父线程。

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

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

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

    //...
}

我错过了什么?


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

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

1 回答 1

8

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

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

您应该查看以下信号:

void QIODevice::bytesWritten(qint64 bytes) [信号]

每次将数据的有效负载写入设备时都会发出此信号。bytes 参数设置为写入此有效负载的字节数。bytesWritten() 不是递归发出的;如果您重新进入事件循环或在连接到 bytesWritten() 信号的插槽内调用 waitForBytesWritten(),则不会重新发送该信号(尽管 waitForBytesWritten() 仍可能返回 true)。

和...

void QIODevice::readyRead() [信号]

每次有新数据可用于从设备读取时,都会发出一次此信号。它只会在新数据可用时再次发出,例如当网络数据的新负载到达您的网络套接字时,或者当新的数据块已附加到您的设备时。

readyRead() 不会递归发出;如果您重新进入事件循环或在连接到 readyRead() 信号的插槽内调用 waitForReadyRead(),则不会重新发送该信号(尽管 waitForReadyRead() 仍可能返回 true)。

实现从 QIODevice 派生的类的开发人员注意:当新数据到达时,您应该始终发出 readyRead() (不要仅仅因为缓冲区中还有数据要读取而发出它)。不要在其他条件下发出 readyRead()。

我通过命令行编写了两个示例,您可以在此处找到:

命令行编写器异步示例

命令行阅读器同步示例

于 2014-05-09T16:35:12.353 回答