Skip to content


Raster calc: refresh layers list if a layer is renamed or added/removed
Browse files Browse the repository at this point in the history
Fixes #20601 - bug: Raster calculator produces empty results layer and no error message if input layer is one that has been renamed in QGIS layers panel
  • Loading branch information
elpaso committed Nov 29, 2018
1 parent 49da1c3 commit 1672d43
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
49 changes: 32 additions & 17 deletions python/plugins/processing/algs/qgis/ui/
Expand Up @@ -28,10 +28,13 @@
import re
import json

from qgis.utils import iface
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QTextCursor
from qgis.PyQt.QtWidgets import (QLineEdit, QPushButton, QLabel,
QComboBox, QSpacerItem, QSizePolicy)
QComboBox, QSpacerItem, QSizePolicy,

from qgis.core import (QgsProcessingUtils,
Expand Down Expand Up @@ -187,8 +190,20 @@ def fillPredefined(self):
def setList(self, options):
self.options = options
for opt in options.keys():
entries = QgsRasterCalculatorEntry.rasterEntries()

def _find_source(name):
for entry in entries:
if entry.ref == name:
return entry.raster.source()
return ''

for name in options.keys():
item = QListWidgetItem(name, self.listWidget)
tooltip = _find_source(name)
if tooltip:
item.setData(Qt.ToolTipRole, tooltip)

def setValue(self, value):
Expand All @@ -202,28 +217,28 @@ class ExpressionWidgetWrapper(WidgetWrapper):
def _panel(self, options):
return ExpressionWidget(options)

def _get_options(self):
entries = QgsRasterCalculatorEntry.rasterEntries()
options = {}
for entry in entries:
options[entry.ref] = entry.ref
return options

def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
entries = QgsRasterCalculatorEntry.rasterEntries()
options = {}
for entry in entries:
options[entry.ref] = entry.ref
return self._panel(options)
if iface is not None and iface.layerTreeView() is not None and iface.layerTreeView().layerTreeModel() is not None:
return self._panel(self._get_options())
elif self.dialogType == DIALOG_BATCH:
return QLineEdit()
layers = self.dialog.getAvailableValuesOfType([QgsProcessingParameterRasterLayer], [QgsProcessingOutputRasterLayer])
options = {self.dialog.resolveValueDescription(lyr): "{}@1".format(self.dialog.resolveValueDescription(lyr)) for lyr in layers}
return self._panel(options)
self.widget = self._panel(options)
return self.widget

def refresh(self):
# TODO: check if avoid code duplication with self.createWidget
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
options = {}
for lyr in layers:
for n in range(lyr.bandCount()):
options[] = '{:s}@{:d}'.format(, n + 1)
def refresh(self, *args):

def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsrastercalcdialog.cpp
Expand Up @@ -153,6 +153,7 @@ QVector<QgsRasterCalculatorEntry> QgsRasterCalcDialog::rasterEntries() const
return entries;

void QgsRasterCalcDialog::setExtentSize( int width, int height, QgsRectangle bbox )
mNColumnsSpinBox->setValue( width );
Expand All @@ -168,6 +169,7 @@ void QgsRasterCalcDialog::setExtentSize( int width, int height, QgsRectangle bbo
void QgsRasterCalcDialog::insertAvailableRasterBands()
mAvailableRasterBands = QgsRasterCalculatorEntry::rasterEntries().toList();
for ( const auto &entry : qgis::as_const( mAvailableRasterBands ) )
QgsRasterLayer *rlayer = entry.raster;
Expand Down

0 comments on commit 1672d43

Please sign in to comment.