Diseñando e implementando un QFileDialog con QtDesigner y PyQGIS

Un QFileDialog es la aplicación que en Qt nos permite visualizar, mediante una GUI de usuario, el directorio en el cual se quiere grabar un archivo. Si el archivo ya existe se pide confirmación de sobre escritura. La implementación de la grabación hay que hacerla con código extra, es decir, no está incluida en QFileDialog.

Para diseñar la interface, se va a usar QtDesigner. En la imagen siguiente se observan las modificaciones que se realizaron en la plantilla por defecto. En ella se redujo un poco el tamaño, se preservaron los botones (Ok, Cancel) y se añadieron una editLine para el nombre del archivo a grabar y un pushButton para la selección del directorio de grabación. El label del pushButton se cambió al ya convencional “…” y el de la editLine se incluyó con el texto “Select ouput layer”. Los cambios se salvaron como ui_output_file_dialog_base.ui.

output_file1

El comando de compilación usando pyuic4 se detalla en la imagen a continuación:

output_file2

El código python que produjo la compilación de la interface es 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(400, 140)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(40, 80, 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(110, 30, 231, 20))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(350, 30, 31, 21))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.label = QtGui.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(20, 30, 91, 16))
        self.label.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))

Para poder visualizar la interface y que realice la búsqueda del directorio en el el cual se quiere grabar, seleccione adecuadamente el nombre del archivo correspondiente y, finalmente, lo grabe tenemos el código siguiente (con el nombre de output_file.py):

# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QFileDialog
from qgis.gui import QgsMessageBar
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('c:/Users')
        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
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

Los comentarios señalan las porciones de código que se incluyeron en la plantilla que implementa la aplicación. Sin embargo, las líneas comentadas entre la 18 y la 20 hacen lo mismo que las de las líneas 40 y 41; siendo la primera forma la que generalmente se utiliza en la plantilla generada por el Plugin Builder.

Cuando se ejecuta la aplicación en la Python Console de QGIS se obtiene:

output_file3

Cuando se hace click en el pushButton con el label “…”, aparece el QFileDialog de la imagen siguiente. Desde allí navego hasta el folder Desktop y selecciono el nombre de mi archivo sin la extensión (name_of_my_file). Click en ‘Save’ para aceptar el path.

output_file4

En la imagen siguiente se observa que la ruta al archivo a grabar, con extensión *.txt, fue escogida adecuadamente. Click en Ok para aceptar y grabar los cambios.

output_file5

En la función ‘save_file’ del programa principal se observa que el texto que debería albergar el archivo es simplemente “My Text”. Cuando se abre name_of_my_file.txt se visualiza, en la imagen siguiente, que la aplicación funcionó adecuadamente.

output_file6

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

4 respuestas a Diseñando e implementando un QFileDialog con QtDesigner y PyQGIS

  1. Pingback: Agregando una QgsMapLayerComboBox (PyQGIS) a un QDialog diseñado previamente con QtDesigner | El Blog de José Guerrero

  2. Pingback: Cómo introducir valores numéricos en un plugin de QGIS a través de una QLineEdit | El Blog de José Guerrero

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

  4. Hola buen día, disculpa tengo un problema. Apenas empiezo a aprender sobre PyQgis y estoy realizando los ejemplos de este foro. Me podrías ayudar?
    Al momento de compilar el archivo output_file.py, me da el siguiente error:
    “QWidget: Must construct a QApplication before a QPaintDevice”

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