From ac40fd93b71eeeb1868520605aeb2001983fb54b Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 27 Oct 2024 09:02:29 -0500 Subject: [PATCH] Ensure widgets are always updated on the main thread Fixes crashes and widget freezes --- scwx-qt/source/scwx/qt/main/main_window.cpp | 25 +++++++++-------- scwx-qt/source/scwx/qt/map/map_widget.cpp | 28 ++++++++++--------- scwx-qt/source/scwx/qt/ui/line_label.cpp | 30 ++++++++++++++------- 3 files changed, 48 insertions(+), 35 deletions(-) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 2c744ff7..cebdab48 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -494,12 +494,11 @@ void MainWindow::on_actionOpenNexrad_triggered() map::MapWidget* currentMap = p->activeMap_; // Make sure the parent window properly repaints on close - connect( - dialog, - &QFileDialog::finished, - this, - [this]() { update(); }, - Qt::QueuedConnection); + connect(dialog, + &QFileDialog::finished, + this, + static_cast(&MainWindow::update), + Qt::QueuedConnection); connect( dialog, @@ -560,12 +559,11 @@ void MainWindow::on_actionOpenTextEvent_triggered() dialog->setAttribute(Qt::WA_DeleteOnClose); // Make sure the parent window properly repaints on close - connect( - dialog, - &QFileDialog::finished, - this, - [this]() { update(); }, - Qt::QueuedConnection); + connect(dialog, + &QFileDialog::finished, + this, + static_cast(&MainWindow::update), + Qt::QueuedConnection); connect(dialog, &QFileDialog::fileSelected, @@ -1003,7 +1001,8 @@ void MainWindowImpl::ConnectAnimationSignals() { for (auto map : maps_) { - map->update(); + QMetaObject::invokeMethod( + map, static_cast(&QWidget::update)); } }); connect(timelineManager_.get(), diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index da5bef38..d3c7fefc 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -357,7 +357,7 @@ void MapWidgetImpl::ConnectSignals() connect(placefileManager_.get(), &manager::PlacefileManager::PlacefileUpdated, widget_, - [this]() { widget_->update(); }); + static_cast(&QWidget::update)); // When the layer model changes, update the layers connect(layerModel_.get(), @@ -903,7 +903,8 @@ void MapWidget::SelectTime(std::chrono::system_clock::time_point time) void MapWidget::SetActive(bool isActive) { p->context_->settings().isActive_ = isActive; - update(); + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void MapWidget::SetAutoRefresh(bool enabled) @@ -1026,7 +1027,8 @@ void MapWidget::UpdateMouseCoordinate(const common::Coordinate& coordinate) if (keyboardModifiers != Qt::KeyboardModifier::NoModifier || keyboardModifiers != p->lastKeyboardModifiers_) { - update(); + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } p->lastKeyboardModifiers_ = keyboardModifiers; @@ -1292,7 +1294,7 @@ void MapWidgetImpl::AddPlacefileLayer(const std::string& placefileName, connect(placefileLayer.get(), &PlacefileLayer::DataReloaded, widget_, - [this]() { widget_->update(); }); + static_cast(&QWidget::update)); } std::string @@ -1319,7 +1321,7 @@ void MapWidgetImpl::AddLayer(const std::string& id, connect(layer.get(), &GenericLayer::NeedsRendering, widget_, - [this]() { widget_->update(); }); + static_cast(&QWidget::update)); } catch (const std::exception&) { @@ -1825,12 +1827,11 @@ void MapWidgetImpl::RadarProductViewConnect() if (radarProductView != nullptr) { - connect( - radarProductView.get(), - &view::RadarProductView::ColorTableLutUpdated, - this, - [this]() { widget_->update(); }, - Qt::QueuedConnection); + connect(radarProductView.get(), + &view::RadarProductView::ColorTableLutUpdated, + widget_, + static_cast(&QWidget::update), + Qt::QueuedConnection); connect( radarProductView.get(), &view::RadarProductView::SweepComputed, @@ -1863,7 +1864,7 @@ void MapWidgetImpl::RadarProductViewDisconnect() { disconnect(radarProductView.get(), &view::RadarProductView::ColorTableLutUpdated, - this, + widget_, nullptr); disconnect(radarProductView.get(), &view::RadarProductView::SweepComputed, @@ -1913,7 +1914,8 @@ void MapWidgetImpl::SetRadarSite(const std::string& radarSite) void MapWidgetImpl::Update() { - widget_->update(); + QMetaObject::invokeMethod( + widget_, static_cast(&QWidget::update)); if (UpdateStoredMapParameters()) { diff --git a/scwx-qt/source/scwx/qt/ui/line_label.cpp b/scwx-qt/source/scwx/qt/ui/line_label.cpp index 0b2f8f75..03dbcaf6 100644 --- a/scwx-qt/source/scwx/qt/ui/line_label.cpp +++ b/scwx-qt/source/scwx/qt/ui/line_label.cpp @@ -81,45 +81,57 @@ void LineLabel::set_border_width(std::size_t width) { p->borderWidth_ = width; p->pixmapDirty_ = true; - updateGeometry(); - update(); + + QMetaObject::invokeMethod(this, &QWidget::updateGeometry); + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_highlight_width(std::size_t width) { p->highlightWidth_ = width; p->pixmapDirty_ = true; - updateGeometry(); - update(); + + QMetaObject::invokeMethod(this, &QWidget::updateGeometry); + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_line_width(std::size_t width) { p->lineWidth_ = width; p->pixmapDirty_ = true; - updateGeometry(); - update(); + + QMetaObject::invokeMethod(this, &QWidget::updateGeometry); + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_border_color(boost::gil::rgba8_pixel_t color) { p->borderColor_ = color; p->pixmapDirty_ = true; - update(); + + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_highlight_color(boost::gil::rgba8_pixel_t color) { p->highlightColor_ = color; p->pixmapDirty_ = true; - update(); + + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_line_color(boost::gil::rgba8_pixel_t color) { p->lineColor_ = color; p->pixmapDirty_ = true; - update(); + + QMetaObject::invokeMethod( + this, static_cast(&QWidget::update)); } void LineLabel::set_line_settings(settings::LineSettings& lineSettings)