Все, что вам нужно сделать для обновления растрового изображения из любого потока , - это выполнить соответствующий код в основном потоке. Это берет на себя все блокировки и все остальное. Предполагается, что современное многопоточное программирование должно быть простым: если нет, возможно, вы слишком стараетесь:)
Например, предположим, что вы используете QLabel
для отображения изображения (зачем изобретать свой собственный виджет?!):
/// This function is thread-safe. It can be invoked from any thread.
void setImageOn(const QImage & image, QLabel * label) {
auto set = [image, label]{
label->setPixmap(QPixmap::fromImage(image));
};
if (label->thread() == QThread::currentThread())
set();
else {
QObject sig;
sig.connect(&sig, &QObject::destroyed, label, set);
}
}
Теперь вы можете делать все правильно и удалять устаревшие изображения - нет смысла устанавливать изображение, если в очереди событий есть более новые изображения. Это было бы единственной причиной для использования собственного виджета. Подробнее см. этот ответ .
Примечание (не относится к вашему коду): если вам нужно вызвать QWidget::update
из за пределами реализации виджета, вы делаете что-то очень неправильно. Если вы используете стандартный виджет Qt, вам никогда не нужно это делать. Если у вас есть собственный виджет, и ему нужно, чтобы его пользователь вызвал update
, значит, вы его неправильно спроектировали. Вот и все, что нужно.