From b444c012b99b19de5bd5ee3d57388a0343f9f1af Mon Sep 17 00:00:00 2001 From: Jean Felder Date: Sat, 9 Nov 2024 10:53:05 +0100 Subject: [PATCH] qgisapp: Update raster layer style when render details have changed `QgsRasterLayer` updates the GUI (the renderer widget and the legend) when the rendered values are updated. This does not work when multiple canvas are displayed because each canvas causes a renderer update. This issue is fixed by removing the GUI update from the raster layer code. With this change, when the rendered values are updated, these statistics are propagated to the canvas by the use of a `QgsRenderedItemDetails`: `QgsRenderedCalculatedResults`. Then, only the main canvas is notified of this change and updates the GUI accordingly. --- src/app/qgisapp.cpp | 38 ++++++++++++++++++++++++++++++ src/app/qgisapp.h | 2 ++ src/core/raster/qgsrasterlayer.cpp | 5 ---- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index a4a5d942c682..149b8c05cd25 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -446,6 +446,8 @@ #include "devtools/querylogger/qgsappquerylogger.h" #include "devtools/querylogger/qgsqueryloggerwidgetfactory.h" #include "devtools/profiler/qgsprofilerwidgetfactory.h" +#include "qgsrendereditemresults.h" +#include "qgsrenderedcalculatedresults.h" #include "browser/qgsinbuiltdataitemproviders.h" @@ -1071,6 +1073,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers mMapCanvas = new QgsMapCanvas( centralWidget ); mMapCanvas->setObjectName( QStringLiteral( "theMapCanvas" ) ); mMapCanvas->setFlags( Qgis::MapCanvasFlag::ShowMainAnnotationLayer ); + connect( mMapCanvas, &QgsMapCanvas::calculatedRenderDetailsChanged, this, &QgisApp::onCalculatedRenderDetailsChanged ); // before anything, let's freeze canvas redraws QgsCanvasRefreshBlocker refreshBlocker; @@ -17588,3 +17591,38 @@ void QgisApp::showEvent( QShowEvent *event ) } } ); } + +void QgisApp::onCalculatedRenderDetailsChanged() +{ + const QgsRenderedItemResults *renderedItemResults = mMapCanvas->renderedItemResults( false ); + if ( !renderedItemResults ) + { + return; + } + + const QList items = renderedItemResults->renderedItems(); + QList computedLayerIds; + for ( const QgsRenderedItemDetails *item : renderedItemResults->renderedItems() ) + { + if ( const QgsRenderedCalculatedResults *calculatedResults = dynamic_cast< const QgsRenderedCalculatedResults *>( item ) ) + { + computedLayerIds.append( calculatedResults->layerId() ); + } + } + + if ( !computedLayerIds.empty() ) + { + for ( QgsMapLayer *layer : mMapCanvas->layers() ) + { + // refresh the legend and style of the raster layer + if ( QgsRasterLayer *rasterLayer = qobject_cast( layer ) ) + { + if ( computedLayerIds.contains( rasterLayer->id() ) ) + { + rasterLayer->emitStyleChanged(); + emit rasterLayer->rendererChanged(); + } + } + } + } +} diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 7514bb96ccde..ce3323bd985b 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -1445,6 +1445,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow void onSnappingConfigChanged(); + void onCalculatedRenderDetailsChanged(); + /** * Triggers validation of the specified \a crs. */ diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index 04f70f668ed2..bc518636fc0f 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -1613,9 +1613,6 @@ bool QgsRasterLayer::refreshRenderer( QgsRasterRenderer *rasterRenderer, const Q } } - emit repaintRequested(); - emitStyleChanged(); - emit rendererChanged(); return true; } @@ -1650,8 +1647,6 @@ bool QgsRasterLayer::refreshRenderer( QgsRasterRenderer *rasterRenderer, const Q } } - emitStyleChanged(); - emit rendererChanged(); refreshed = true; } }