Подтвердить что ты не робот

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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