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