Ensure widgets are always updated on the main thread

Fixes crashes and widget freezes
This commit is contained in:
Dan Paulat 2024-10-27 09:02:29 -05:00
parent 194638f759
commit ac40fd93b7
3 changed files with 48 additions and 35 deletions

View file

@ -494,12 +494,11 @@ void MainWindow::on_actionOpenNexrad_triggered()
map::MapWidget* currentMap = p->activeMap_; map::MapWidget* currentMap = p->activeMap_;
// Make sure the parent window properly repaints on close // Make sure the parent window properly repaints on close
connect( connect(dialog,
dialog, &QFileDialog::finished,
&QFileDialog::finished, this,
this, static_cast<void (MainWindow::*)()>(&MainWindow::update),
[this]() { update(); }, Qt::QueuedConnection);
Qt::QueuedConnection);
connect( connect(
dialog, dialog,
@ -560,12 +559,11 @@ void MainWindow::on_actionOpenTextEvent_triggered()
dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setAttribute(Qt::WA_DeleteOnClose);
// Make sure the parent window properly repaints on close // Make sure the parent window properly repaints on close
connect( connect(dialog,
dialog, &QFileDialog::finished,
&QFileDialog::finished, this,
this, static_cast<void (MainWindow::*)()>(&MainWindow::update),
[this]() { update(); }, Qt::QueuedConnection);
Qt::QueuedConnection);
connect(dialog, connect(dialog,
&QFileDialog::fileSelected, &QFileDialog::fileSelected,
@ -1003,7 +1001,8 @@ void MainWindowImpl::ConnectAnimationSignals()
{ {
for (auto map : maps_) for (auto map : maps_)
{ {
map->update(); QMetaObject::invokeMethod(
map, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
}); });
connect(timelineManager_.get(), connect(timelineManager_.get(),

View file

@ -357,7 +357,7 @@ void MapWidgetImpl::ConnectSignals()
connect(placefileManager_.get(), connect(placefileManager_.get(),
&manager::PlacefileManager::PlacefileUpdated, &manager::PlacefileManager::PlacefileUpdated,
widget_, widget_,
[this]() { widget_->update(); }); static_cast<void (QWidget::*)()>(&QWidget::update));
// When the layer model changes, update the layers // When the layer model changes, update the layers
connect(layerModel_.get(), connect(layerModel_.get(),
@ -903,7 +903,8 @@ void MapWidget::SelectTime(std::chrono::system_clock::time_point time)
void MapWidget::SetActive(bool isActive) void MapWidget::SetActive(bool isActive)
{ {
p->context_->settings().isActive_ = isActive; p->context_->settings().isActive_ = isActive;
update(); QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void MapWidget::SetAutoRefresh(bool enabled) void MapWidget::SetAutoRefresh(bool enabled)
@ -1026,7 +1027,8 @@ void MapWidget::UpdateMouseCoordinate(const common::Coordinate& coordinate)
if (keyboardModifiers != Qt::KeyboardModifier::NoModifier || if (keyboardModifiers != Qt::KeyboardModifier::NoModifier ||
keyboardModifiers != p->lastKeyboardModifiers_) keyboardModifiers != p->lastKeyboardModifiers_)
{ {
update(); QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
p->lastKeyboardModifiers_ = keyboardModifiers; p->lastKeyboardModifiers_ = keyboardModifiers;
@ -1292,7 +1294,7 @@ void MapWidgetImpl::AddPlacefileLayer(const std::string& placefileName,
connect(placefileLayer.get(), connect(placefileLayer.get(),
&PlacefileLayer::DataReloaded, &PlacefileLayer::DataReloaded,
widget_, widget_,
[this]() { widget_->update(); }); static_cast<void (QWidget::*)()>(&QWidget::update));
} }
std::string std::string
@ -1319,7 +1321,7 @@ void MapWidgetImpl::AddLayer(const std::string& id,
connect(layer.get(), connect(layer.get(),
&GenericLayer::NeedsRendering, &GenericLayer::NeedsRendering,
widget_, widget_,
[this]() { widget_->update(); }); static_cast<void (QWidget::*)()>(&QWidget::update));
} }
catch (const std::exception&) catch (const std::exception&)
{ {
@ -1825,12 +1827,11 @@ void MapWidgetImpl::RadarProductViewConnect()
if (radarProductView != nullptr) if (radarProductView != nullptr)
{ {
connect( connect(radarProductView.get(),
radarProductView.get(), &view::RadarProductView::ColorTableLutUpdated,
&view::RadarProductView::ColorTableLutUpdated, widget_,
this, static_cast<void (QWidget::*)()>(&QWidget::update),
[this]() { widget_->update(); }, Qt::QueuedConnection);
Qt::QueuedConnection);
connect( connect(
radarProductView.get(), radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
@ -1863,7 +1864,7 @@ void MapWidgetImpl::RadarProductViewDisconnect()
{ {
disconnect(radarProductView.get(), disconnect(radarProductView.get(),
&view::RadarProductView::ColorTableLutUpdated, &view::RadarProductView::ColorTableLutUpdated,
this, widget_,
nullptr); nullptr);
disconnect(radarProductView.get(), disconnect(radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
@ -1913,7 +1914,8 @@ void MapWidgetImpl::SetRadarSite(const std::string& radarSite)
void MapWidgetImpl::Update() void MapWidgetImpl::Update()
{ {
widget_->update(); QMetaObject::invokeMethod(
widget_, static_cast<void (QWidget::*)()>(&QWidget::update));
if (UpdateStoredMapParameters()) if (UpdateStoredMapParameters())
{ {

View file

@ -81,45 +81,57 @@ void LineLabel::set_border_width(std::size_t width)
{ {
p->borderWidth_ = width; p->borderWidth_ = width;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
updateGeometry();
update(); QMetaObject::invokeMethod(this, &QWidget::updateGeometry);
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_highlight_width(std::size_t width) void LineLabel::set_highlight_width(std::size_t width)
{ {
p->highlightWidth_ = width; p->highlightWidth_ = width;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
updateGeometry();
update(); QMetaObject::invokeMethod(this, &QWidget::updateGeometry);
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_line_width(std::size_t width) void LineLabel::set_line_width(std::size_t width)
{ {
p->lineWidth_ = width; p->lineWidth_ = width;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
updateGeometry();
update(); QMetaObject::invokeMethod(this, &QWidget::updateGeometry);
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_border_color(boost::gil::rgba8_pixel_t color) void LineLabel::set_border_color(boost::gil::rgba8_pixel_t color)
{ {
p->borderColor_ = color; p->borderColor_ = color;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
update();
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_highlight_color(boost::gil::rgba8_pixel_t color) void LineLabel::set_highlight_color(boost::gil::rgba8_pixel_t color)
{ {
p->highlightColor_ = color; p->highlightColor_ = color;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
update();
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_line_color(boost::gil::rgba8_pixel_t color) void LineLabel::set_line_color(boost::gil::rgba8_pixel_t color)
{ {
p->lineColor_ = color; p->lineColor_ = color;
p->pixmapDirty_ = true; p->pixmapDirty_ = true;
update();
QMetaObject::invokeMethod(
this, static_cast<void (QWidget::*)()>(&QWidget::update));
} }
void LineLabel::set_line_settings(settings::LineSettings& lineSettings) void LineLabel::set_line_settings(settings::LineSettings& lineSettings)