我正在使用QtSerialPort库通过 USB 与虚拟 COM 端口通信。COM 端口返回数据并在使用 QtSerialPort 给出的示例项目对其进行测试时正常工作,但当我将其作为项目的一部分运行时失败。
我检查了导致 QtSerialPort 被实例化的实例化链和线程,发现有些奇怪。结果如下。
main()
MainWindow (Thread 0xbf8dbe0) // Thread "A"
HardwareManager (Thread 0xbf8dbe0) // Thread "A"
QSerialPort (Thread 0xbfb95f0) // Thread "B" !?
在我的代码中,main() 函数实例化了 MainWindow,而 MainWindow 又实例化了 HardwareManager 并将其存储为私有变量。当 HardwareManager 被实例化时,它也会实例化 QSerialPort 实例,以便它可以正确地与 COM 端口通信。
但是,您会注意到上面我的 QSerialPort与父对象以及它的父对象位于不同的线程中(它在线程 B 中,而两个祖先都在线程 A 中)。我认为这个其他线程导致我的信号/插槽失败。如果我dumpObjectInfo,它会将我的 Signal/Slot 列为已设置,但事件永远不会触发。
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
以上是我用来创建新串行端口并将其连接到正确插槽的代码。实际的波特率、奇偶校验和数据/停止位配置分别发生(并且工作正常,如 QtSerialPort 提供的示例应用程序中所测试的那样)。
有没有人知道为什么这个特定对象(QSerialPort 实例)在不同的线程中被实例化?我试过“moveToThread”来切换线程关联,但似乎没有任何效果。
我还在Qt 项目论坛上发过帖子,但还没有有用的回复。
编辑: 以下是调用链中的相关代码:
// 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, SIGNAL(readyRead()), this, SLOT(readSerialData()));
当 QSerialPort 准备好被读取时(它有数据要提供),它会触发readyRead
信号(至少,它应该如此)。此信号在 Qt 示例项目中正确触发,但我从未在我的应用程序中收到该信号。我相信我没有收到信号的原因是因为这些线程问题。