c – QtSerialPort插入错误的线程,导致信号/插槽失败

我正在使用 QtSerialPort库通过USB与虚拟COM端口通话.当使用QtSerialPort给出的示例项目进行测试时,COM端口返回数据并正常工作,但是当我作为项目的一部分运行时,COM端口将失败.

我检查了实例链和线程,导致QtSerialPort被实例化,发现有点奇怪.结果如下.

main()
  MainWindow (Thread 0xbf8dbe0)        // Thread "A"
    HardwareManager (Thread 0xbf8dbe0) // Thread "A"
      QSerialPort (Thread 0xbfb95f0)   // Thread "B" !?

在我的代码中,main()函数实例化一个MainWindow,它又实例化了一个HardwareManager并将其存储为一个私有变量.当HardwareManager被实例化时,它还实例化QSerialPort实例,以便它可以正确地与COM端口通信.

但是,您会注意到我的QSerialPort与父对象不同的线程,以及它的父对象(它在线程B中,而祖先在线程A中).我认为这个其他线程导致我的信号/插槽失败.如果我dumpObjectInfo,它列出了我的信号/插槽设置,但事件永远不会触发.

this->serial = new QSerialPort();
connect(this->serial,SIGNAL(readyRead()),this,SLOT(readSerialData());

以上是我用来创建新的串行端口并将其连接到正确的插槽的代码.实际的波特率,奇偶校验和数据/停止位配置分别发生(正常工作,如QtSerialPort提供的示例应用程序中所测试的).

有没有人有任何洞察,为什么这个特定的对象(QSerialPort实例)正在不同的线程中实例化?我尝试过“movetoThread”来切换线程关联,但是似乎没有任何效果.

我也做了post on the Qt Project Forums,但还没有任何有用的回应.

任何帮助是赞赏.

编辑:
以下是呼叫链中的相关代码

// main()
QApplication a(argc,argv)
MainWindow window = new MainWindow(); // [1]
MainWindow.show();
return a.exec();

// MainWindow::MainWindow() [1]
this->toolController = new QtToolController(this);
HardwareManager *manager = new HardwareManager(this->toolController); // [2]

// HardwareManager::HardwareManager() [2]
this->serial = new QSerialPort();
connect(this->serial,SLOT(readSerialData()));

当QSerialPort准备好读取(它有数据提供)时,它会触发readyRead信号(至少应该是).这个信号在Qt示例项目中正常启动,但我从来没有在我的应用程序中获取信号.我相信我没有得到信号的原因是因为这些线程问题.

解决方法

您可以使用 QueuedConnection捕获来自不同线程的信号.
connect(this->serial,SLOT(readSerialData()),Qt::QueuedConnection);

这样,当控件返回到它的事件循环时,这个插槽应该在主线程的上下文中执行.

此外,this post似乎建议您不要为QtSerialPort设置父级(可以说是因为movetoThread不适用于具有父级的QObjects).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...