Создание экземпляра 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 находится в другая нить чем родительский объект, а также его родительский объект (он находится в потоке 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, но я никогда не получаю сигнал в своем приложении. Я считаю, что причина, по которой я не получаю сигнал, из-за проблем с нитями.

10

Решение

Вы могли бы использовать QueuedConnection для ловли сигналов из другого потока.

connect(this->serial, SIGNAL(readyRead()),
this, SLOT(readSerialData()), Qt::QueuedConnection);

Таким образом, слот должен выполняться в контексте вашего основного потока, как только элемент управления возвращается в свой цикл обработки событий.

Также, эта почта кажется, предлагает вам не устанавливать родителя для QtSerialPort (вероятно, потому что moveToThread не работает на объектах QObjects с родителями).

2

Другие решения

В духе обеспечения доступности ответов для всех, кто сталкивался с этой проблемой, проблема была связана со сборками Release / Debug. Библиотека QtSerialPort была собрана ТОЛЬКО для моей среды Release, и по какой-либо причине при запуске моего приложения в режиме отладки ссылка на Release QtSerialPort была бы связана с потерей контекста потока.

Чтобы это исправить, я убедился, что собрал правильную версию библиотеки, а затем заверил, что у меня есть ссылка на правильную версию для моей среды.

1

По вопросам рекламы [email protected]