按照官方文档,我正在尝试这样做:
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
作为父线程的主线程而不是我创建的线程。
如果我没有在构造函数中实例化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;
}
答案 0 :(得分:7)
简而言之,像这样使用QtSerialPort模块是一个坏主意。
我们基于QIODevice设计了这个模块,它已经为您的GUI应用程序提供了使用QSerialPort类的非阻塞机制。
您应该查看以下信号:
void QIODevice::bytesWritten(qint64 bytes) [signal]
每次将数据有效负载写入设备时都会发出此信号。 bytes参数设置为在此有效负载中写入的字节数。 bytesWritten()不是递归发出的;如果重新进入事件循环或在连接到bytesWritten()信号的槽内调用waitForBytesWritten(),则不会重新发送信号(尽管waitForBytesWritten()仍然可以返回true)。
和...
void QIODevice::readyRead() [signal]
每当有新数据可供设备读取时,此信号就会发出一次。只有在新数据可用时才会再次发出,例如网络数据的新有效负载已经到达您的网络套接字,或者新的数据块已经附加到您的设备上。
readyRead()不是递归发出的;如果你重新进入事件循环或在连接到readyRead()信号的槽内调用waitForReadyRead(),则不会重新发送信号(尽管waitForReadyRead()仍然可以返回true)。
对于实现从QIODevice派生的类的开发人员的注意事项:当新数据到达时,您应该始终发出readyRead()(仅因为仍有待在缓冲区中读取数据而不发出它)。不要在其他条件下发出readyRead()。
我通过命令行写了两个例子,你可以在这里找到: