QtSerialPortライブラリを使用して、USB 経由で仮想 COM ポートと通信しています。COM ポートはデータを返し、QtSerialPort で指定されたサンプル プロジェクトでテストすると正しく動作しますが、プロジェクトの一部として実行すると失敗します。
QtSerialPort がインスタンス化されるまでのインスタンス化チェーンとスレッドを調べたところ、少し奇妙なことがわかりました。結果は以下のとおりです。
main()
MainWindow (Thread 0xbf8dbe0) // Thread "A"
HardwareManager (Thread 0xbf8dbe0) // Thread "A"
QSerialPort (Thread 0xbfb95f0) // Thread "B" !?
私のコードでは、main() 関数が MainWindow をインスタンス化し、次にそれが HardwareManager をインスタンス化し、それをプライベート変数として格納します。HardwareManager がインスタンス化されると、QSerialPort インスタンスもインスタンス化されるため、COM ポートと適切に通信できます。
ただし、上記のように、私の QSerialPort は親オブジェクトとは別のスレッドにあり、親オブジェクトでもあります (両方の祖先がスレッド A にあるのに対し、スレッド B にあります)。この他のスレッドが私のシグナル/スロットの失敗を引き起こしていると思います。dumpObjectInfoを実行すると、Signal/Slot が設定されていると表示されますが、イベントは発生しません。
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
上記は、新しいシリアル ポートを作成して適切なスロットに接続するために使用するコードです。実際のボー、パリティ、およびデータ/ストップ ビットの構成は個別に行われます (QtSerialPort が提供するサンプル アプリでテストされているように、正しく動作します)。
この特定のオブジェクト (QSerialPort インスタンス) が別のスレッドでインスタンス化されている理由について、誰かが洞察を持っていますか? スレッドの関連付けを切り替えるために「moveToThread」を試しましたが、何も機能していないようです。
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, SIGNAL(readyRead()), this, SLOT(readSerialData()));
QSerialPort から読み取る準備ができると (提供するデータがある場合)、readyRead
シグナルを発します (少なくとも、発火するはずです)。このシグナルは Qt のサンプル プロジェクトでは正しく発火しますが、私のアプリケーションではシグナルを受け取りません。シグナルが届かないのは、これらのスレッドの問題が原因だと思います。