Qt - излучает сигнал из потока c++

Я хочу выпустить сигнал из потока C++ (std :: thread) в Qt.

Как мне это сделать?

Ответ 1

Вы определенно можете излучать сигнал из потока (QThread, std::thread или even boost::thread). Только вы должны быть осторожны с пятым параметром функции подключения (Qt::ConnectionType):

Если Qt::DirectConnection: слот вызывается немедленно (из текущего потока), когда сигнал испускается. Если Qt::QueuedConnection: слот вызывается, когда управление возвращается к циклу событий потока получателя. Слот выполняется в потоке приемника.

См. ConnectionType-enum для получения дополнительных параметров.

Проблема не в том, из какого потока вы испускаете сигнал, это больше из того потока, который вызывается слотом. Например, я думаю, что QLabel::setText должен быть выполнен из потока владельца QLabel (скорее всего, основного потока). Так что если вы излучать сигнал, подключенный к QLabel setText из потока, соединение должно быть сделано с помощью Qt::AutoConnection, Qt::QueuedConnection или Qt::BlockingQueuedConnection.

Ответ 2

Вы, вероятно, не должны генерировать сигнал Qt из std::thread -created в целом, не заботясь. См. Ответ Jpo38: вопросы типа подключения и т.д.

Если поток запускает некоторый цикл событий Qt, вы, вероятно, могли бы. См. Темы и QObject

Существует (возможно, специфичная для Unix) работа, выполняющая то же самое, что и для сигналов Unix с Qt: используйте канал из вашей std::thread в основной поток.

Но, как прокомментировал Йоахим Пилеборг, вы должны сделать свой собственный QThread. Это самый простой и, возможно, самый короткий (с точки зрения исходного кода), и вам просто нужно скопировать и вставить какой-то существующий пример и адаптировать его к вашим потребностям.

Помните, что AFAIK только основной поток должен выполнять манипуляции с Qt GUI. Вы не должны использовать QWidget (и т.д.) Вне основного потока! (BTW, GTK имеет такое же ограничение, по крайней мере, в Linux: только основной поток должен использовать системные протоколы X Windows)

Ответ 3

Если вы сохраняете указатель на свой QObject, вы можете использовать один из членов QMetaObject::invokeMethod http://qt-project.org/doc/qt-5/qmetaobject.html#invokeMethod

Вероятно, вам придется использовать Qt::QueuedConnection чтобы ваш сигнал Qt::QueuedConnection в правильном потоке (а не в std :: thread). Помните, что ваш сигнал не будет вызван сразу.