2

I need to print a message after the user pushes the button "Prueba". The message must contain coordinates "x", "y" from the user's click in the map canvas. I don't know why the user input has not activated.

Here is my code attempt:

import os
import processing
from qgis.gui import QgsMapToolEmitPoint
from qgis.core import QgsRasterLayer
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
from qgis.core import QgsProject
from qgis.utils import iface
from PyQt5.QtWidgets import QMessageBox
# This loads your .ui file so that PyQt can populate your plugin 
FORM_CLASS, _ = uic.loadUiType(os.path.join(
 os.path.dirname(__file__), 'MorfoCuencas_dialog_base.ui'))
class MyPlugin(QtWidgets.QDialog, FORM_CLASS):
 def __init__(self, parent=None):
 """Constructor."""
 super(MyPlugin, self).__init__(parent)
 
 self.setupUi(self)
 
 self.loadLayers()
 self.Boton.clicked.connect(self.Pbtn_clicked)
 self.Prueba.clicked.connect(self.Prueba_clic)
 
 def loadLayers(self):
 for layer in QgsProject.instance().mapLayers().values():
 self.cbbCargarCapas.addItem(layer.name(),layer)
 def Pbtn_clicked(self):
 entrada=self.cbbCargarCapas.currentData()
 directorioTrabajo=self.lneSalida.text()
 self.Proceso(entrada,directorioTrabajo)
 iface.messageBar().pushMessage("la ruta de salida es: "+str(entrada.name()))
 
 def Prueba_clic(self):
 def display_point( pointTool ): 
 puntox=str(pointTool[0])
 puntoy=str(pointTool[1])
 QMessageBox.information(iface.mainWindow(), "Capa Activa", 'El punto es ' +puntox+','+puntoy)
 self.canvas = iface.mapCanvas()
 self.pointTool = QgsMapToolEmitPoint(self.canvas)
 self.pointTool.canvasClicked.connect( display_point )
 self.canvas.setMapTool( self.pointTool )
 QMessageBox.information(iface.mainWindow(), "Mensaje", 'Presionó botón prueba')
Taras
35.7k5 gold badges77 silver badges151 bronze badges
asked Jul 10, 2021 at 2:31
1
  • Where do you want these coordinates to be printed? Commented Jul 10, 2021 at 9:36

1 Answer 1

2

What you have there is not a plugin class but a dialog class. I am not sure exactly how you are running this code or trying to install it as a plugin, but the first thing I would suggest is that you need to create separate classes for plugin logic and dialog (they may or may not be separate files). The main plugin class should take the qgisinterface object in its constructor and save a reference to self.iface so that when accessing the interface you should use the self.iface object. A couple of other suggested changes are making your display_point() function an instance method of your main plugin class, not nested inside another method, and declaring the canvas and map tool objects inside the __init__() method of the main plugin class.

Also, I strongly recommend using custom QGIS widgets such as QgsMapLayerComboBox instead of a generic QComboBox. This is more of a "best practice" thing rather a functional issue, but would give you a few benefits such as loading all map layers in the project by default (you can apply filters) so you wouldn't need your loadLayers() method at all. Your QGIS installation should come with a version of Qt Designer with custom widgets enabled. You can open it via a batch file in the bin folder (see below).

enter image description here

To help you out, I have created an example plugin based on your code snippet, to give you an idea of a working structure which you can test and adapt.

The example plugin is here (my github repo for plugin examples):

https://github.com/benwirf/QGIS_Example_Plugins

You can download the whole repo as a zip file and just copy the My_Plugin folder into your QGIS plugins directory and enable it from the Plugin Manager.

Below is a gif showing the plugin working:

enter image description here

The .ui in file Qt Designer looks like below (showing QGIS custom widgets and widget object names):

enter image description here

The contents of the other plugin files are:

__init__.py:

def classFactory(iface):
 from .my_plugin import MyPlugin
 return MyPlugin(iface)

my_plugin_dialog.py:

import os
from PyQt5.QtWidgets import QDialog
from PyQt5 import uic
# This loads your .ui file so that PyQt can populate your plugin 
FORM_CLASS, _ = uic.loadUiType(os.path.join(
 os.path.dirname(__file__), 'MorfoCuencas_dialog_base.ui'))
class MyPluginDialog(QDialog, FORM_CLASS):
 def __init__(self, parent=None):
 """Constructor."""
 super(MyPluginDialog, self).__init__(parent)
 
 self.setupUi(self)

my_plugin.py:

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAction, QMessageBox
from qgis.gui import QgsMapToolEmitPoint
from .my_plugin_dialog import MyPluginDialog
class MyPlugin:
 def __init__(self, iface):
 self.iface = iface
 self.canvas = self.iface.mapCanvas()
 self.pointTool = QgsMapToolEmitPoint(self.canvas)
 self.msg = QMessageBox()
 self.dlg = MyPluginDialog()
 def initGui(self):
 self.action = QAction('My Plugin', self.iface.mainWindow())
 self.action.triggered.connect(self.run)
 self.iface.addToolBarIcon(self.action)
 
 # Declare your signal-slot connections
 self.dlg.finished.connect(lambda: self.iface.actionPan().trigger())
 self.dlg.Boton.clicked.connect(self.Pbtn_clicked)
 self.dlg.Prueba.clicked.connect(self.Prueba_clic)
 self.dlg.pb_close.clicked.connect(lambda: self.dlg.close())
 self.pointTool.canvasClicked.connect(self.display_point)
 
 def unload(self):
 self.iface.removeToolBarIcon(self.action)
 del self.action
 def Pbtn_clicked(self):
 #Fetch current layer in QgsMapLayerComboBox
 entrada = self.dlg.cbbCargarCapas.currentLayer()
# directorioTrabajo=self.lneSalida.text()
# self.Proceso(entrada,directorioTrabajo)
 self.iface.messageBar().pushMessage("la ruta de salida es: "+str(entrada.name()))
 def Prueba_clic(self):
 self.dlg.showMinimized()
 self.canvas.setMapTool(self.pointTool)
 def display_point(self, pnt):
 puntox = str(pnt[0])
 puntoy = str(pnt[1])
 QMessageBox.information(self.iface.mainWindow(), "Capa Activa", 'El punto es ' +puntox+','+puntoy)
 def run(self):
 self.dlg.show()

And metadata.txt:

[general]
name=MyPlugin
description=A small test plugin
about=About this test plugin
version=1.0
qgisMinimumVersion=3.0
author=Your Name
[email protected]
repository=URL to the code repository
answered Jul 11, 2021 at 4:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.