Я использую QtSerialPort библиотека для общения с виртуальным COM-портом через USB. 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 находится в другая нить чем родительский объект, а также его родительский объект (он находится в потоке B, в то время как оба предка находятся в потоке A). Я думаю, что этот другой поток вызывает сбой моих сигналов / слотов. Если я dumpObjectInfo, он показывает мой сигнал / слот как настроенный, но события никогда не запускаются.
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
Выше приведен код, который я использую для создания нового последовательного порта и подключения его к соответствующему слоту. Фактическая конфигурация скорости передачи, четности и данных / стоп-бита происходит отдельно (и работает должным образом, как было протестировано в примере приложения, предоставляемого QtSerialPort).
Кто-нибудь знает, почему этот конкретный объект (экземпляр QSerialPort) создается в другом потоке? Я пытался «moveToThread», чтобы переключить ассоциацию потоков, но, похоже, ничего не работает.
Я также сделал пост на форумах Qt Project, но еще не получили полезных ответов.
Редактировать:
Ниже приведен соответствующий код в цепочке вызовов:
// 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, но я никогда не получаю сигнал в своем приложении. Я считаю, что причина, по которой я не получаю сигнал, из-за проблем с нитями.
Вы могли бы использовать QueuedConnection для ловли сигналов из другого потока.
connect(this->serial, SIGNAL(readyRead()),
this, SLOT(readSerialData()), Qt::QueuedConnection);
Таким образом, слот должен выполняться в контексте вашего основного потока, как только элемент управления возвращается в свой цикл обработки событий.
Также, эта почта кажется, предлагает вам не устанавливать родителя для QtSerialPort (вероятно, потому что moveToThread не работает на объектах QObjects с родителями).
В духе обеспечения доступности ответов для всех, кто сталкивался с этой проблемой, проблема была связана со сборками Release / Debug. Библиотека QtSerialPort была собрана ТОЛЬКО для моей среды Release, и по какой-либо причине при запуске моего приложения в режиме отладки ссылка на Release QtSerialPort была бы связана с потерей контекста потока.
Чтобы это исправить, я убедился, что собрал правильную версию библиотеки, а затем заверил, что у меня есть ссылка на правильную версию для моей среды.