5 votos

Uso de los widgets QgsColorButton

Plataforma: Windows 10 QGis 2.18.14 QT Desiner 4.8.5 PyQT4

Estoy creando un formulario personalizado utilizando QT Designer para ser utilizado en una capa junto con una rutina en Python.

Sólo para probar he añadido un QgsColorButton en el formulario.

La idea sería seleccionar el color en el cuadro de opciones de color de este botón y el color seleccionado se guardaría en la tabla de atributos de la característica de la capa.

Intenté hacer una pequeña rutina en Python sólo para comprobar si podía acceder a las propiedades del QgsColorButton cuando se abrió el formulario, pero no puede ni siquiera pasar por esta fase.

¿Algún consejo para solucionar este problema?


En la consola el código parece ser sencillo, pero me cuesta entender con el acceso al QgsColorButton del formulario creado en QT Designer.

Esta sería la plantilla de formulario con múltiples QgsColorButton .

enter image description here

Necesito acceder al QgsColorButton con algo como el siguiente código:

from qgis.core import *
from qgis.gui import *
from PyQt4.QtGui import *
from PyQt4.QtCore import *

def form_open (Dialog, layer_id, feature_id):
     global form
     form = Dialog
     btn = form.findChild (QgsColorButton, "mColorButton")
     btn.setColor (QColor (255, 0, 0, 127))
     layer = iface.activeLayer ()
     provider = layer.dataProvider ()
     feature = layer.selectedFeatures ()
     feature ['Color_01'] = btn.color ()
     layer.startEditing ()
     layer.updateFeature (feature)
     layer.commitChanges ()

El código de arriba parece ser simple, pero no funciona como usted quiere.

Un código de segunda parte sería el QgsColorButton cargar el color guardado en la tabla de atributos al abrir el formulario.

No tengo ni idea de cómo hacer que esto funcione.


@Francisco Raga, ¡perfecto! El único cambio que tengo que hacer es cambiar el método LoadColor.

def LoadColor ():
    color_value = ToolFeature ["Color"]    
    if not isinstance (color_value, QPyNullVariant):
    mColorButton.setColor(color_value)
    return

Pero esto devolvió el siguiente error.

Traceback (most recent call last):
   File "", line 1, in
   File "", line 22, in UpdateColorForm
   File "", line 29, in LoadColor
AttributeError: 'QPushButton' object has no attribute 'setColor'

Cuando introduzco el siguiente comando en la consola de Python del QGIS dir (QgsColorButton) devuelve todos los métodos de QgsColorButton y el setColor aparece en la lista.

He compilado la plantilla ui para comprobar qué métodos y argumentos quiero devolver al método

self.mColorButton.setColor (QtGui.QColor (0, 0, 255))

No sé qué se puede hacer, porque en la consola de QGIS el setColor es reconocido y ejecuta el código perfectamente.

Intenté usar el código de abajo, pero no pasa nada. No se muestra ningún mensaje de error y el fondo del mColorButton no cambia de color con el valor cargado desde el "Color" de la característica.

def LoadColor():
    color_value = ToolFeature["Color"]    
    if not isinstance(color_value, QPyNullVariant):
        style = "QWidget { background-color: %s; }" % color_value
        mColorButton.setAutoFillBackground(True)
        mColorButton.setStyleSheet(style)
        mColorButton.update()
    return

1 votos

En QGIS 2.x debe utilizar QgsColorButtonV2. Es el botón más bonito con el desplegable para los colores usados recientemente y los preestablecidos.

5voto

BWW Puntos 302

He realizado una documentación completa para todas las clases de QGIS GUI de Python

Puede encontrar muestras ilustradas de ambos:

0 votos

Ya he mirado este sitio, pero todo el mundo es un ejemplo utilizando la consola de QGIS. Todos los ejemplos que he encontrado en internet son todos genéricos hechos para consola. Mi duda es la que he explorado antes. Múltiples QgsColorButton en un formulario hecho en QT Designer como opciones para guardar los colores seleccionados incluso después de cerrar el formulario. Creo que aún no he escrito nada sobre esto, ya que hace unos días que estoy buscando en internet una solución y todo lo que he encontrado son ejemplos de formularios hechos en la consola de QGIS.

1 votos

Es una documentación muy completa. Desearía que esto estuviera vinculado desde el sitio web oficial de QGIS como un recurso adicional, ya que sólo lo encontré desde esta respuesta.

5voto

Andy Brandi Puntos 650

Creo que he entendido tu pregunta. Tengo una capa que tiene una columna "Color" el cuando abrir mi diálogo y seleccionar un color usando QgsColorButton . Esta característica seleccionada ACTUALIZACIÓN el "Color" utilizando el color seleccionado.

Y el segundo objetivo es que, el atributo seleccionado tenga un color en el "Color" y mi QgsColorButton Actualiza el valor usando esto.

Este es mi diálogo:

enter image description here

Y la capa de prueba, que tiene un "Color" columna

enter image description here

Mi diálogo compilado tiene esta señal:

QtCore.QObject.connect(self.mColorButton, QtCore.SIGNAL(_fromUtf8("colorChanged(QColor)")), BaseDialog.UpdateColor)

Y mi BaseDialog "Diálogo de plugins"

import os.path
from qgis.core import *
from qgis.gui import *
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from gui.generated.ui_BaseDialog import Ui_BaseDialog

class BaseDialog(QtGui.QDialog, Ui_BaseDialog):
    def __init__(self, iface):
        QtGui.QDialog.__init__(self)
        self.setupUi(self)
        self.iface = iface
        self.plugin_dir = os.path.dirname(os.path.abspath(__file__))
        self.LoadColor()

    # Load color from attribue
    def LoadColor(self):
        selected_features = self.iface.activeLayer().selectedFeatures()
        for color in selected_features:
            color_value=color["Color"]
            self.mColorButton.setColor(QColor(color_value))
        return

    # Update lineEdit
    def UpdateColor(self,color):
        self.lineEdit.setText(color.name())
        self.UpdateFeature(color)
        return

    # Update Attribute value
    def UpdateFeature(self,color):
        layer = self.iface.activeLayer()
        provider = layer.dataProvider()
        fldIdx = provider.fieldNameIndex("Color") # Get Column
        features = layer.selectedFeatures()
        if not features:
            return
        layer.startEditing()
        for feature in features:
            feature[fldIdx] = color.name()
            layer.updateFeature(feature)

        layer.commitChanges()
        return

Entonces cuando abro el diálogo y tengo cualquier característica seleccionada y esta característica tiene cualquier valor en la columna de atributos, esto se carga en el ColorButton.

Añadir gif.

enter image description here

NOTA : Si tiene este error al compilar su .ui

ImportError: No hay módulo llamado qgscolorbutton

Abre el .ui con algún editor de texto y reemplaza:

<customwidgets>
  <customwidget>
   <class>QgsColorButton</class>
   <extends>QPushButton</extends>
   <header>qgscolorbutton.h</header>
  </customwidget>
 </customwidgets>

con:

 <customwidgets>
  <customwidget>
   <class>QgsColorButton</class>
   <extends>QPushButton</extends>
   <header>qgis.gui</header>
  </customwidget>
 </customwidgets>

Y compilar de nuevo.


ACTUALIZACIÓN: Crear una función init de Python: "Proporcionar código en este diálogo"

No estoy seguro de que esta alternativa para tu ejemplo pueda ayudarte,pero solo necesitas un archivo .ui y un solo script.

Tengo un simple .ui

enter image description here

Y mi función init de python es : Tenga en cuenta que combobox han seleccionado "Proporcionar el código en este diálogo"

enter image description here

Código:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.PyQt.QtWidgets import QWidget

mColorButton=None
lineEdit=None
ToolFeature=None
ToolLayer=None

def UpdateColorForm(dialog, layer, feature):
    global ToolFeature
    global ToolLayer
    global mColorButton
    global lineEdit
    ToolFeature = feature
    ToolLayer = layer
    mColorButton = dialog.findChild(QWidget, "mColorButton")
    lineEdit = dialog.findChild(QLineEdit, "lineEdit")
    mColorButton.connect(mColorButton, SIGNAL("colorChanged(QColor)"), UpdateColor)
    LoadColor()

def LoadColor():
    color_value = ToolFeature["Color"]
    if not isinstance(color_value, QPyNullVariant):
        lineEdit.setText(color_value)
    return

def UpdateColor(color):
    lineEdit.setText(color.name())
    UpdateFeature(color)
    return

def UpdateFeature(color):
    provider = ToolLayer.dataProvider()
    fldIdx = provider.fieldNameIndex("Color")
    ToolLayer.startEditing()
    ToolFeature[fldIdx] = color.name()
    ToolLayer.updateFeature(ToolFeature)
    ToolLayer.commitChanges()
    return

No necesitas compilar .ui o algo así, y cuando cambies el valor, cambia el attibute y cuando abras el diálogo, carga el valor actual en el lineedit.

enter image description here

Si prefiere actualizar el valor al pulsar el botón Ok necesita cambiar las señales, lea este y eliminar la señal actual de UpdateColor

ACTUALIZACIÓN 2 : Uso del widget QPushButton

Es tan extraño pero QgsColorButton no es accesible, pero podemos solucionarlo con un simple botón qpushbutton

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.PyQt.QtWidgets import QWidget

mColorButton = None
lineEdit = None
ToolFeature = None
ToolLayer = None

def UpdateColorForm(dialog, layer, feature):
    global ToolFeature
    global ToolLayer
    global mColorButton
    global lineEdit

    ToolFeature = feature
    ToolLayer = layer
    mColorButton = dialog.findChild(QWidget, "pushButton")
    mColorButton.clicked.connect(color_picker)

    # Default Color
    UpdateColorPicker("#2b71e2")

    lineEdit = dialog.findChild(QLineEdit, "lineEdit")
    LoadColor()

def color_picker():
    color_value = QColorDialog.getColor()
    if color_value.isValid():
        UpdateColor(color_value)
    return

def LoadColor():
    color_value = ToolFeature["Color"]
    if not isinstance(color_value, QPyNullVariant):
        lineEdit.setText(color_value)
        UpdateColorPicker(color_value)
    return

def UpdateColorPicker(color):
    style = """
            QWidget {
            background-color:  %s;
            border-style: outset;
            border-width: 2px;
            border-radius: 10px;
            border-color: beige;
            font: bold 14px;
            min-width: 10em;
            padding: 6px;
            } """ % color
    mColorButton.setAutoFillBackground(True)
    mColorButton.setStyleSheet(style)
    mColorButton.update()
    return

def UpdateColor(color):
    lineEdit.setText(color.name())
    UpdateFeature(color)
    UpdateColorPicker(color.name())
    return

def UpdateFeature(color):
    provider = ToolLayer.dataProvider()
    fldIdx = provider.fieldNameIndex("Color")
    ToolLayer.startEditing()
    ToolFeature[fldIdx] = color.name()
    ToolLayer.updateFeature(ToolFeature)
    ToolLayer.commitChanges()
    return

y el resultado funciona perfectamente.

Espero que sea de ayuda

Probado con Windows 10 QGis 2.18.14

4voto

Yada Puntos 9489

Puede probarlo incluso sin ningún diálogo personalizado porque QgsColorButton tiene el método show() (no es una clase C++ compleja). Así, en la consola de Python de QGIS:

>>>from qgis.gui import QgsColorButton
>>>w = QgsColorButton()
>>>w.move(500,500)
>>>w.setMinimumSize(300, 25)
>>>w.show()

y se obtuvo algo similar a:

enter image description here

Después de seleccionar #b36910 color (notación HTML) y haga clic en Aceptar, el resultado fue el siguiente:

enter image description here

Finalmente, de nuevo en la consola de Python con la siguiente línea de código:

>>>w.color().name()
u'#b36910'

se corroboró el color del nombre de la selección. Esta cadena se puede guardar en la tabla de atributos de la característica de la capa.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X