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')
-
Where do you want these coordinates to be printed?Taras– Taras ♦2021年07月10日 09:36:36 +00:00Commented Jul 10, 2021 at 9:36
1 Answer 1
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).
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:
The .ui in file Qt Designer looks like below (showing QGIS custom widgets and widget object names):
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
Explore related questions
See similar questions with these tags.