Agregando una QgsMapLayerComboBox (PyQGIS) a un QDialog diseñado previamente con QtDesigner

En el post pasado se consideró la implementación y diseño de un QFileDialog, con QtDesigner y PyQGIS, que permitía navegar y escoger el directorio de grabación y el nombre de un archivo de texto plano. En esta oportunidad vamos a modificar el archivo principal y el que contiene el Dialog sin compilar mediante pyuic4 este último.

El objetivo es incluir una QgsMapLayerComboBox, que es una aplicación de qgis.gui, que permite automáticamente seleccionar y/o filtrar las layers que se encuentran en el registro de la Map Legend de QGIS sin necesidad de programarla; tal como habría sido necesario si se hubiese diseñado con el QtDesigner.

Para ello, lo primero que hice fue clonar y modificar el output_file_dialog.py para hacerle espacio y colocarle el label a la QgsMapLayerComboBox. El código finalmente obtenido fue el siguiente:

# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'ui_output_file_dialog_base.ui'
#
# Created: Thu Aug 06 00:39:15 2015
#      by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(450, 140)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(40, 90, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
        self.lineEdit = QtGui.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(150, 60, 231, 20))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(390, 60, 31, 21))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.label = QtGui.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(20, 60, 110, 16))
        self.label.setObjectName(_fromUtf8("label"))
        #new label
        self.label2 = QtGui.QLabel(Dialog)
        self.label2.setGeometry(QtCore.QRect(20, 20, 110, 16))
        self.label2.setObjectName(_fromUtf8("label"))
 
        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
 
    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
        self.pushButton.setText(_translate("Dialog", "...", None))
        self.label.setText(_translate("Dialog", "Select output file", None))
        self.label2.setText(_translate("Dialog", "Select layer", None))

Para incluir la QgsMapLayerComboBox tuve primero que hacer algunas pruebas en la Python Console de QGIS con sus métodos de clase. Para ello me fue muy útil la aplicación getPat diseñada con anterioridad. Así, pude establecer sólo tres líneas y su ubicación dentro del programa principal que fueron las siguientes:

.
.
.
win = QgsMapLayerComboBox(dlg)   #create a QgsMapLayerComboBox
win.setFixedWidth(231)
win.move(150, 20)
.
.
.

El código completo del programa principal, output_file.py, se señala a continuación:

# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QFileDialog
from qgis.gui import QgsMessageBar, QgsMapLayerComboBox
import output_file_dialog
from os import chdir
 
class OutputFile(QtGui.QDialog):
     
    def __init__(self):
        QtGui.QDialog.__init__(self)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing:
        # self.<objectname>
        self.ui = output_file_dialog.Ui_Dialog()
        self.ui.setupUi(self)
 
#        #As in a QGIS plugin
#        self.ui.lineEdit.clear()
#        self.ui.pushButton.clicked.connect(self.select_output_file)
 
    def select_output_file(self):
        chdir('/home/zeito')
        filename = QFileDialog.getSaveFileName(self, "Select output file ","", '*.txt')
        self.ui.lineEdit.setText(filename)
        self.save_file()
 
    def save_file(self):
        filename = self.ui.lineEdit.text()
        output_file = open(filename, 'w')
        output_file.write("My text")
        output_file.close()
 
# Create the dialog and keep reference
reload(output_file_dialog)
 
dlg = OutputFile()      #create Dialog object

win = QgsMapLayerComboBox(dlg)   #create a QgsMapLayerComboBox
win.setFixedWidth(231)
win.move(150, 20)

dlg.show()                 #show Dialog object
 
dlg.ui.lineEdit.clear()   #clear text in lineEdit object
dlg.ui.pushButton.clicked.connect(dlg.select_output_file)   #send signal if pushButton is clicked

Al probar la aplicación en la Python Console, con dos capas vectoriales y una ráster escogidas arbitrariamente, se obtiene lo siguiente:

combo_box1

Lo importante de esta clase QgsMapLayerComboBox es que contiene métodos heredados de otras clases que nos permiten seleccionar (las QgsVectorLayer o QgsRasterLayer) o filtrar (por ejemplo QgsMapLayerProxyModel y sus miembros enumerados) por tipo de layers en la Combo Box con poco esfuerzo de programación.

Esta entrada fue publicada en PyQGIS, QGIS, Software Libre. Guarda el enlace permanente.

2 respuestas a Agregando una QgsMapLayerComboBox (PyQGIS) a un QDialog diseñado previamente con QtDesigner

  1. Pingback: Las clases Qgs…ComboBox de qgis.gui (PyQGIS) | El Blog de José Guerrero

  2. Pingback: Newsletter Octubre 2015 | El Blog de José Guerrero

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s