часто обновляйте QLabel с данными изображения с сервера - PullRequest
0 голосов
/ 02 января 2012

Я пишу программу, которая должна показывать изображение в QLabel в QWidget.Изображения отправляются с сервера.Во-первых, у меня есть поток, который отвечает за соединение и получение данных с сервера.Когда данные получены, поток сокетов отправляет сигнал gotNewData(Imagedata), который подключен к слоту QWidget updateImage(Imagedata).В слоте updateImage(Imagedata) я конвертирую данные изображения, которые я получаю с сервера, в QImage, масштабирую изображение и создаю QPixmap, для которого я установил QLabel.Моя проблема в том, что при обработке функции updateImage(Imagedata) сокет получает другие пакеты с новыми изображениями и снова и снова посылает сигнал на QWidget.Это логично, потому что поток сокетов не заботится о том, завершена ли уже функция updateImage(Imagedata), которая была вызвана предыдущим сигнальным вызовом, или нет.Мой вопрос: есть ли методы, как я могу синхронизировать поток моего сокета с функцией QWidget updateImage(Imagedata)?

1 Ответ

0 голосов
/ 02 января 2012

Там определенно есть. Вопрос в том, чего именно вы хотите добиться, если новое изображение будет получено, а старое еще обрабатывается. Если вы хотите пропустить новый и обработать старый до конца, я бы порекомендовал вызывать blockSignals при отправке объекта - это уничтожает звонки и звонки, но qt не позволяет блокировать получение сигналов, просто отправку. Модификация, которая не сильно повлияет на производительность и не смущает другие сети, которые могут быть реализованы, будет состоять в том, чтобы создать прокси-объект QObject в виджете, содержащем метку, затем с помощью moveToThread () переместить его в сетевой поток и использовать для этого blockSignals. объект. Естественно, этот объект нуждается в сигнале такой же подписи, как и фактический передаваемый сигнал. Созданный объект, хотя и с другой привязкой к потоку, логически останется владельцем графического интерфейса и должен быть удален им.

Другой подход - создать переменную bool processing в вашем объекте и установить для нее значение true, если вы обрабатываете данные. Непосредственно перед установкой его на false вы вызываете QCoreApplication::processEvents();, который обрабатывает все события в очереди событий. В вашем слоте вы должны проверить, установлена ​​ли processing vaiable и пропустить ли что-либо, если это так. Это простая и грубая мысль, но она работает. Обратите внимание, что если у вас есть другие обработчики событий, вызывающие processEvents(); (например, более одной метки, подобной этой) в потоке GUI, некоторые метки могут вообще перестать получать свои данные (заморозить).

Возможно, у вас возникнет соблазн использовать Qt::BlockingQueuedConnection, чтобы заблокировать сетевой поток от получения чего-либо до завершения обработки, но это плохая идея по многим различным причинам (если вы синхронизируете его таким образом, то зачем вам вообще нужен отдельный поток? ) * +1010 *

...