微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

原文地址:https://www.jb51.cc/c/115875.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐