QT Threads рабочий дизайн с блокировкой цикла

я использую qt5 и opencv для создания приложения, которое дает пользовательский интерфейс с использованием qt и выполняет обработку изображений в opencv …..

до сих пор мой дизайн:

  1. я показываю видео и некоторые стандартные элементы управления, такие как кнопки и флажки, используя основную ветку qt
  2. для захвата изображения и его обработки я создал рабочий класс, производный от QObject, и переместил его в поток ….
  3. функция, которая выполняется в рабочем классе (Worker :: process), имеет блокирующий цикл while … который постоянно:
    • захватывает кадр из видео или камеры
    • делает некоторую обработку на нем
    • конвертирует из cv :: Mat в QImage
    • подать сигнал в основной поток для отображения QImage
  4. также, чтобы получить пользовательский ввод, я использовал передачу сигнала от основного потока к рабочим слотам

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

после долгих поисков я нашел решение использовать аргумент Qt :: DirectConnection при подключении сигнала из основного потока к рабочим слотам. это решило проблему в то время.

Теперь мне нужно добавить qtimer или qbasictimer внутри цикла блокировки …. и угадать, что, слот таймера (в случае qtimer) и защищенный обработчик timerEvent (в случае qbasictimer) никогда не будут вызваны. я догадываюсь, что снова блокирует цикл

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

У меня есть два варианта сейчас:

  1. каким-то образом вызвать функцию потоков exec () внутри блокирующего цикла while. поэтому вопрос к гуру:
    «Как я могу вызвать метод thread :: exec () внутри рабочего класса QObject, мне нужна ссылка на поток, выполняющий рабочий, для вызова exec ()» (краткосрочное решение)

  2. изменить всю реализацию ….. и вот вопросы:
    «Какие у меня варианты …..» (долгосрочные)

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

-1

Решение

Внутри блокировки вашего работника, позвоните qApp->processEvents(); периодически.

http://qt-project.org/doc/qt-5.1/qtcore/qcoreapplication.html#processEvents

#include <QApplication>
// ...
void Worker::doWork()
{
while(true)
{
someLongImageProcessingFunction();
qApp->processEvents();
}
}

Это должно позволить обрабатывать слоты и обновлять таймеры.

Использование прямого соединения может позволить вам получить доступ и изменить значения, локальные для вашего работника, но вы должны быть осторожны с безопасностью потоков. Если вы положите QMutexLocker прямо перед вашими значениями, которые изменяются вашим графическим интерфейсом, и прямо перед тем, как ваш рабочий поток использует их, вы должны быть хорошими.

http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html

Также, если вы хотите, чтобы какой-либо из этих слотов работал в рабочем потоке, вам нужно использовать QueuedConnection,

http://qt-project.org/doc/qt-5.1/qtcore/threads.html

http://qt-project.org/doc/qt-5.1/qtcore/qthread.html#details

В некоторых частях документов Qt описывается создание подкласса класса QThread. Другие части рекомендуют модель Worker / Producer и просто используют соединения для настройки того, как вы используете свои потоки. Обычно с моделью Worker / Producer меньше ошибок.

Надеюсь, это поможет.

2

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

Других решений пока нет …

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