Я использую библиотеку QtSerialPort, чтобы поговорить с виртуальным COM-портом через USB. COM-порт возвращает данные и работает правильно при тестировании с примерами проектов с QtSerialPort, но не работает, когда я запускаю его как часть моего проекта.QtSerialPort создает экземпляр в неправильной цепочке, вызывая сбои сигналов/слотов
Я проверил цепочку создания и потоки, которые приводят к созданию экземпляра QtSerialPort, и нашел что-то странное. Результаты приведены ниже.
main()
MainWindow (Thread 0xbf8dbe0) // Thread "A"
HardwareManager (Thread 0xbf8dbe0) // Thread "A"
QSerialPort (Thread 0xbfb95f0) // Thread "B" !?
В моем коде, основной() функция инстанцирует MainWindow, которая, в свою очередь, инстанцирует HardwareManager и сохраняет его в качестве частной переменной. Когда экземпляр HardwareManager создается, он также создает экземпляр QSerialPort, чтобы он мог нормально разговаривать с COM-портом.
Однако, вы заметите выше мой QSerialPort находится в другом потоке, чем родительский объект, а также его родительский объект (это в Thread B, в то время как оба предки в Thread А). Я думаю, что этот другой поток приводит к сбою моих сигналов/слотов. Если I dumpObjectInfo, он перечисляет мой сигнал/слот как настроенный, но события никогда не срабатывают.
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
Выше приведен код, который я использую для создания нового последовательного порта и подключения его к соответствующему слоту. Фактическая конфигурация бит, четность и данные/стоп-бит происходит отдельно (и работает правильно, как проверено в примере приложения QtSerialPort).
Кто-нибудь знает, почему этот конкретный объект (экземпляр QSerialPort) создается в другом потоке? Я попытался «moveToThread», чтобы переключить ассоциацию потоков, но ничего не работает.
Я также сделал post on the Qt Project Forums, но пока не получил полезных ответов.
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, но я никогда не получаю сигнал в своем приложении. Я считаю, что причина, по которой я не получаю сигнал, связана с этими проблемами.
Я не знаю, как работает QT, так что просто дикое предположение: вы создаете 'QSerialPort' в ответ на какое-то событие? Любой шанс, вызванный обработчиком событий в контексте другого потока? – 2013-03-01 16:01:36
Нет. Репликация QSerialPort входит в экземпляр HardwareManager, который находится в экземпляре MainWindow, который вызывается в методе main(). На данный момент не используются сигналы/слоты/обратные вызовы. –
Я считаю, что вам не следует беспокоиться о другой теме, вы должны беспокоиться о том, что не работают только сигнальные/слоты. Покажите нам свой главный, пожалуйста. И дайте некоторую информацию о том, когда должен сломать слот. – ixSci