1

I'm trying to build a QGIS plugin where I need to ask for a file name using a pushButton connected with a QFileDialog object. I've built a simple plugin using the QGIS plugin builder (putting the text 'plugintest' in the six mandatory fields). Then, I modified the original GUI adding a pushButton and a lineEdit objects. The final compiled ui_plugintest.py is

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_plugintest(object):
    def setupUi(self, plugintest):
        plugintest.setObjectName(_fromUtf8("plugintest"))
        plugintest.resize(400, 300)
        self.buttonBox = QtGui.QDialogButtonBox(plugintest)
        self.buttonBox.setGeometry(QtCore.QRect(30, 240, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
        self.pushButton = QtGui.QPushButton(plugintest)
        self.pushButton.setGeometry(QtCore.QRect(140, 140, 99, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.lineEdit = QtGui.QLineEdit(plugintest)
        self.lineEdit.setGeometry(QtCore.QRect(12, 110, 371, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))

        self.retranslateUi(plugintest)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), plugintest.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), plugintest.reject)
        QtCore.QMetaObject.connectSlotsByName(plugintest)

    def retranslateUi(self, plugintest):
        plugintest.setWindowTitle(_translate("plugintest", "plugintest", None))
        self.pushButton.setText(_translate("plugintest", "PushButton", None))

Finally, I've added the code in order to connect the pushButton with the QFileDialog object. The main plugintest.py is

# Import the PyQt and QGIS libraries
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
# Initialize Qt resources from file resources.py
import resources_rc
# Import the code for the dialog
from plugintestdialog import plugintestDialog
import os.path


class plugintest:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n', 'plugintest_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Create the dialog (after translation) and keep reference
        self.dlg = plugintestDialog()

    def initGui(self):
        # Create action that will start plugin configuration
        self.action = QAction(
            QIcon(":/plugins/plugintest/icon.png"),
            u"plugintest", self.iface.mainWindow())
        # connect the action to the run method
        self.action.triggered.connect(self.run)

        # Add toolbar button and menu item
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(u"&plugintest", self.action)

    def unload(self):
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu(u"&plugintest", self.action)
        self.iface.removeToolBarIcon(self.action)

    # run method that performs all the real work
    def run(self):
        # show the dialog
        self.dlg.show()

        #selección de fichero de trabajo
        self.dlg.connect(self.dlg.pushButton,SIGNAL("clicked()"),
                         self.select_file)

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result == 1:
            # do something useful (delete the line containing pass and
            # substitute with your code)
            pass

    def select_file(self):
        #extraigo el nombre del fichero
        filename = QFileDialog.getSaveFileName(None,u"Select file",
                                 options=QFileDialog.DontUseNativeDialog)
        self.dlg.lineEdit.setText(filename)
        return

Apparently, the plugin works, but I've discovered an anormal behavior in a special case. I'll try to explain it by steps:

  1. Load and call the plugin in QGIS. The plugin window appears
  2. Instead of click in the PushButton, click in the Cancel button of the main window (this not should be the normal use, but imagine an user do)
  3. Now, call the plugin again
  4. Push the PushButton and put a file name in the window
  5. Click Save and then the QFileDialog appears again!

This behavior occurs only when the plugin is loaded and the cancel button is clicked, and the plugin reloaded again. I don't know if the problem is a bug in QGIS or I've written the connection in a wrong way. Any ideas?

Thanks

PS: I'm using QGIS 2.4.0 from Debian GNU Linux

1

it looks like your plugin is connecting twice times to the select_file slot. It should be enough to move the pushButton signal to __init__() function just after the self.dlg = plugintestDialog() or you also can initialize the self.dlg by the run() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.