sábado, 7 de septiembre de 2019

Cómo acceder a los PyQt5.QtWidgets.QLineEdit de los Objetos QgsRasterHistogramWidget para colocar valores máximos y mínimos de capas ráster con PyQGIS 3

En un post anterior se utilizaron objetos de la clase QgsRasterHistogramWidget para obtener histogramas de capas ráster con PyQGIS 3. En las imágenes del widget obtenido por programación en PyQGIS se observa que los valores mínimos y máximos de cada banda (cuatro en total) no son tomados automáticamente por éste. Los espacios destinados a albergar dichos valores, probablemente unos objetos del tipo QLineEDit, permanecen siempre vacios.

Para rellenar esos objetos con los valores correspondientes primero hay que averiguar cuál es el nombre de esos objetos. Ello se logra con la secuencia de comandos siguiente:

>>>layer = iface.activeLayer()
>>>w = QgsRasterHistogramWidget(layer)
>>>widgets = [ [i.objectName(), i] for i in w.findChildren(QWidget) ]
>>>widgets

donde se observa que de los 35 posibles resultados los objetos de tipo QLineEdit corresponden a 'leHistoMin' y 'leHistoMax'.

[['mpPlot', <class 'PyQt5.QtWidgets.QFrame'>], ['QwtPlotTitle', <class 'PyQt5.QtWidgets.QFrame'>], 
['QwtPlotFooter', <class 'PyQt5.QtWidgets.QFrame'>], ['QwtPlotAxisYLeft', <class 'PyQt5.QtWidgets.QWidget'>], 
['QwtPlotAxisYRight', <class 'PyQt5.QtWidgets.QWidget'>], ['QwtPlotAxisXTop', <class 'PyQt5.QtWidgets.QWidget'>], 
['QwtPlotAxisXBottom', <class 'PyQt5.QtWidgets.QWidget'>], ['QwtPlotCanvas', <class 'PyQt5.QtWidgets.QFrame'>], 
['', <class 'PyQt5.QtWidgets.QFrame'>], ['QwtLegendView', <class 'PyQt5.QtWidgets.QScrollArea'>], 
['QwtLegendViewport', <class 'PyQt5.QtWidgets.QWidget'>], ['QwtLegendViewContents', <class 'PyQt5.QtWidgets.QWidget'>], 
['', <class 'PyQt5.QtWidgets.QFrame'>], ['qt_scrollarea_hcontainer', <class 'PyQt5.QtWidgets.QWidget'>], 
['', <class 'PyQt5.QtWidgets.QScrollBar'>], ['qt_scrollarea_vcontainer', <class 'PyQt5.QtWidgets.QWidget'>], 
['', <class 'PyQt5.QtWidgets.QScrollBar'>], ['stackedWidget2', <class 'PyQt5.QtWidgets.QStackedWidget'>], 
['page', <class 'PyQt5.QtWidgets.QWidget'>], ['btnHistoCompute', <class 'PyQt5.QtWidgets.QPushButton'>], 
['page2_2', <class 'PyQt5.QtWidgets.QWidget'>], ['mHistogramProgress', <class 'PyQt5.QtWidgets.QProgressBar'>], 
['page1_2', <class 'PyQt5.QtWidgets.QWidget'>], ['frame_2', <class 'PyQt5.QtWidgets.QFrame'>], ['leHistoMax', <class 'PyQt5.QtWidgets.QLineEdit'>], ['btnHistoMax', <class 'PyQt5.QtWidgets.QToolButton'>], 
['leHistoMin', <class 'PyQt5.QtWidgets.QLineEdit'>], ['btnHistoMin', <class 'PyQt5.QtWidgets.QToolButton'>], 
['label_9', <class 'PyQt5.QtWidgets.QLabel'>], ['label_11', <class 'PyQt5.QtWidgets.QLabel'>], ['cboHistoBand', <class 'PyQt5.QtWidgets.QComboBox'>], ['mSaveAsImageButton', <class 'PyQt5.QtWidgets.QtoolButton'>], 
['label_10', <class 'PyQt5.QtWidgets.QLabel'>], ['btnHistoActions', <class 'PyQt5.QtWidgets.QToolButton'>], 
['', <class 'PyQt5.QtWidgets.QMenu'>]]

Para evitar tener que lidiar con todos ellos filtramos los que nos interesan con el código siguiente:

>>>widgets = [ i for i in w.findChildren(QWidget)
            if any([i.objectName() == 'leHistoMin', i.objectName() == 'leHistoMax']) ] 
>>>widgets
[<PyQt5.QtWidgets.QLineEdit object at 0x7f16bbda1828>, <PyQt5.QtWidgets.QLineEdit object at 0x7f16bbda1948>]

Finalmente, el código completo queda de la manera siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
layer = iface.activeLayer()

renderer = layer.renderer()
provider = layer.dataProvider()

nb = layer.bandCount()
bands = range(1, nb+1)
 
minimums = [ provider.bandStatistics(band, QgsRasterBandStats.All).minimumValue 
             for band in bands ]
 
maximums = [ provider.bandStatistics(band, QgsRasterBandStats.All).maximumValue 
             for band in bands ]

w = QgsRasterHistogramWidget(layer)
w.setWindowTitle('Layer Properties-' + layer.name() + '|Histogram')
band = 3

w.setSelectedBand(band)  #default band 1
w.setFixedWidth(600)
w.computeHistogram(True)
w.refreshHistogram()
w.show()

children = w.children()

children[1].setFixedWidth(575) #'mpPlot'

pref = children[5]  # QMenu of preferences

pref_actions = pref.actions()

option = 0

name_actions = [ action.text() for action in pref_actions ]

print(name_actions)

for action in pref_actions:
    if action.text() == 'Draw as lines':
        action.setChecked(option)
        action.trigger()

    if action.text() == 'Show selected band':
        action.trigger()

all_widgets = [ i for i in w.findChildren(QWidget) ]
all_widgets_names = [ [i.objectName(), type(i)] for i in w.findChildren(QWidget) ]

widgets = [ i for i in w.findChildren(QWidget)
            if any([i.objectName() == 'leHistoMin', i.objectName() == 'leHistoMax']) ] 

widgets[0].setText(str(maximums[band-1]))
widgets[1].setText(str(minimums[band-1]))

Al ejecutar el código anterior (para la banda 3) en la Python Console de QGIS se puede observar que ahora si se despliegan en las QLineEDit los valores mínimos y máximos correspondientes.



No hay comentarios: