Qt, обновление виджета и взаимодействие с пользовательским интерфейсом - PullRequest
1 голос
/ 05 июня 2011

Я новичок в Qt, и мне очень полезно учиться.Я пытаюсь объединить существующий код C ++ с новым графическим интерфейсом Qt.По сути, идея состоит в том, чтобы изображения, извлеченные из файла .avi, обрабатывались в серверной части и затем отображались в виде QLabel на экране.Мне удалось получить следующий бит кода для правильного отображения кадров:

while (frame = cvQueryFrame(capture))
{
    // Some processing code...

    QImage qImageFrame((uchar*) frame->imageData, frame->width, frame->height, frame->widthStep, QImage::Format_RGB888);
    qImageFrame = qImageFrame.rgbSwapped();
    QPixmap qFrame;

    qFrame.convertFromImage(qImageFrame);
    label->setPixmap(qFrame);
    label->repaint();

    cvWaitKey(10);
}

Теперь, однако, это, очевидно, означает, что пользовательский интерфейс перестает реагировать на ввод пользователя, пока все кадры из фильма не отображаются,Как это сделать?

Примечание: я выполняю обработку с использованием библиотеки openCV, которая ожидает изображения в определенном формате.Например, одна вещь, которую я не могу сделать, - это работа с файлом .avi непосредственно в домене Qt.

Ответы [ 4 ]

3 голосов
/ 05 июня 2011

Я не согласен с предположением Тамаса о том, что его ответ является «самым простым» решением.

Самое быстрое, наименее инвазивное решение вашей проблемы - добавить qApp->processEvents(); в ваш цикл.Я бы бросил его после label->repaint(); и посмотрел, что произойдет.

1 голос
/ 05 июня 2011

Иногда самое простое решение - лучшее. Создайте рабочий поток с помощью подкласса QRunnable для декодирования ваших кадров и отправки сигналов обратно в графический интерфейс для обновления кадра. Когда сигналы Qt испускаются между потоками, они ставятся в очередь и отправляются правильно. Особенно в случае одного рабочего потока, у вас не будет головной боли из-за проблем параллелизма. Копирование QImage не является проблемой, поскольку оно использует неявное совместное использование . Чтобы написать свои собственные классы данных с неявным общим доступом, используйте QSharedDataPointer (насколько я знаю, Qt также использует его для внутреннего использования).

1 голос
/ 05 июня 2011

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

Для исходного вопроса: вы должны выполнить обработку в другом потоке.Это сложно, потому что вы можете вызывать функции GUI только из потока пользовательского интерфейса, и вы (я полагаю) не хотите копировать данные изображения слишком много.

Для хорошего сокращения (и указателей)к документации по Qt), посмотрите на передачу сигналов Qt между потоками, один из них - поток GUI? .Обратите внимание, что потребуется дополнительная работа, если вы хотите передать QImage с напрямую.

0 голосов
/ 05 июня 2011

Использование потока - не единственный (или действительно обязательно предпочтительный) способ сделать это.

Ваш пользовательский интерфейс блокирует, потому что вы используете блокирующий режим сна (cvWaitKey).Если вы вместо этого используете QTimer и подключаете его сигнал времени ожидания к слоту, который рисует следующий кадр, то ваш пользовательский интерфейс должен оставаться отзывчивым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...