#1 Tue 16 January 2024 10:20
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
QGIS/Python: recuperer un point
Bonjour,
Je voudrais récupérer un point cliqué dans le canevas
En faisant cela, ca fonctionne
Code:
from qgis.gui import QgsMapToolEmitPoint,Qgis def foo(tool): click = (tool.x(), tool.y()) print (QgsPointXY(tool.x(),tool.y())) canvas = iface.mapCanvas() tool = QgsMapToolEmitPoint(canvas) tool.setCursor(Qt.SizeAllCursor) tool.canvasClicked.connect(foo) canvas.setMapTool(tool)
Par contre, en faisant cela, rien ne se passe
Code:
from qgis.gui import QgsMapToolEmitPoint,Qgis def foo(tool): click = (tool.x(), tool.y()) print (QgsPointXY(tool.x(),tool.y())) def DonnerPoint(): canvas = iface.mapCanvas() tool = QgsMapToolEmitPoint(canvas) tool.setCursor(Qt.SizeAllCursor) tool.canvasClicked.connect(foo) canvas.setMapTool(tool) DonnerPoint()
1) Pouvez-vous me dire pourquoi et que faut-il faire ?
2) Comment cliquer un point avec la touche gauche et arrêter pour récupérer le résultat avec la touche droite de la souris
3) Comment tout simplement récupérer le résultat final?
4) Enfin comment faire en sorte que tout se processus soit appeler par une fonction applicative DonnerPointClique
Merci de vos réponses et bonne journée, PYJ
Hors ligne
#2 Tue 16 January 2024 12:59
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: recuperer un point
Cela ne fonctionne pas car lorsque vous générez le map tool depuis votre fonction vous le stockez dans une variable locale.
Lorsque la fonction a fini de s'exécuter, le ramasse miette de python détruit les variables locales qui ne sont plus utile.
Pour résoudre cela, vous pouvez par exemple travailler avec une classe ou rendre la variable tool global (je vous le déconseille).
Voici un exemple de classe:
Code:
class DonnerPoint(): def __init__(self): self.canvas = iface.mapCanvas() self.tool = QgsMapToolEmitPoint(self.canvas) self.tool.setCursor(Qt.SizeAllCursor) def activate(self): self.tool.canvasClicked.connect(self.on_click) self.canvas.setMapTool(self.tool) def unactivate(self): self.tool.canvasClicked.disconnect(self.on_click) self.canvas.unsetMapTool(self.tool) def on_click(self, point): click = (point.x(), point.y()) print (QgsPointXY(*click)) self.unactivate() p = DonnerPoint() p.activate()
Hors ligne
#3 Tue 16 January 2024 14:12
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: recuperer un point
En prenant ton exemple, cela fonctionne, le point est écrit dans la console ;-)
Toutefois, et c'est là où je bataille depuis un moment, je voudrais que la fonction (complète) de récupération du point soit dans un fichier .py (ex GL_POINT.py et ce parmis d'autres fonction.
Cette fonction devra retourner le point cliqué
Et que la fonction appelante (ex : mon_point = fonction appelé) soit utilisée dans mon code applicatif
- Le Fichier GL_POINT.py contient entre autres ta classe et est un fichier importé
- Le fichier Ma_fonctionalite.py présent dans mon plugin contient par exemple
Code:
sys.path.append(os.environ["GL_PY_FEDERAL"]) import GL_POINT ... mon_point = GL_POINT.DonnerPoint() print (mon_point) ...
Merci encore de ton aide
PYJ
Hors ligne
#4 Tue 16 January 2024 16:08
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: recuperer un point
Si je comprend bien, une approche possible est la suivante
Code:
from qgis.gui import QgsMapToolEmitPoint,Qgis # GL POINT.py class DonnerPoint(QObject): point_clicked = pyqtSignal(QgsPointXY) def __init__(self): super().__init__() self.clicked_point = None self.canvas = iface.mapCanvas() self.tool = QgsMapToolEmitPoint(self.canvas) self.tool.setCursor(Qt.SizeAllCursor) self.tool.canvasClicked.connect(self.on_click) self.canvas.setMapTool(self.tool) def on_click(self, point): self.point_clicked.emit(point) self.clicked_point = point # fonctionnalites.py class MonPlugin(): ... def point_user(self, point): self.point = point self.faire_quelque_chose_avec_le point() def fonctionnalite(self, *args): ... point_requester = DonnerPoint() point_requester.point_clicked.connect(point_user) def faire_quelque_chose_avec_le_point(self): print(self.point)
Il faut faire communiquer votre classe qui demande le point avec votre plugin au moment où l'utilisateur a cliqué. Cela se fait via le l'emission d'un signal qui envoi le point à votre plugin.
Hors ligne
#5 Mon 22 January 2024 09:12
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: recuperer un point
Bonjour
En fait, j'ai tout mis dans le plugin même.
Ca fonctionne je récupère le point cliqué et affiche ses coordonnées dans mon IHM.
Pour terminer, dans l'évènement self.dlg.rejected.connect, je réactive l'outil "Pan"
Challenge !
Il me reste à continuer, notamment en essayant de matérialiser mon curseur avec un rectangle vde qui suivrait la souris tant qu'on ne fera pas de clic.
A ce propos, est-ce que l'évènement move de la souris irait ou bien il n'est actif que si un bouton est enfoncé ?
Bonne journée
PYJ
Hors ligne
#6 Mon 22 January 2024 11:02
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: recuperer un point
Pour une customisation plus poussée, vous devriez penser à implémenter votre propre QgsMapTool plutôt que d'utiliser QgsMapToolEmitPoint qui est un map tool prêt à l'emploi sans grande possibilité de customisation.
Vous pouvez vous inspirer de cette réponse:
https://gis.stackexchange.com/a/45105/98611
Vous pourrez surcharger les événements canvasMoveEnvent et canvasPressEvent ce qui vous permettra d'interagir avec le déplacement de la souris ou son click selon votre logique métier.
[edit] Vous pouvez aussi directement vous connecter au signal du QgsMapToolEmitPoint puisqu'il hérite de QgsMapTool.
Code:
self.tool.canvasMoveEvent.connect(self.on_move)
Et vous définissez on_move avec votre logique à l'intérieur.
Dernière modification par YoLecomte (Mon 22 January 2024 12:51)
Hors ligne
#7 Mon 22 January 2024 14:26
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: recuperer un point
Je fais
Code:
self.point_tool.canvasClicked.connect(self.display_point) self.point_tool.canvasMoveEvent.connect(self.on_move)
Pour le 1er, pas de problème et l'exécution se fait correctement
Pour le 2ème
Code:
self.point_tool.canvasMoveEvent.connect(self.on_move)
J'ai un message d'erreur à l'ouverture:
self.point_tool.canvasMoveEvent.connect(self.on_move)
AttributeError: 'builtin_function_or_method' object has no attribute 'connect'
PYJ
Hors ligne
#8 Tue 23 January 2024 09:18
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: recuperer un point
Effectivement, ce signal n'est pas exposé.
Vous pouvez vous inspirer de ce mapTool pour construire le votre:
https://github.com/qgis/QGIS/blob/maste … MapTool.py
Hors ligne
#9 Wed 24 January 2024 10:53
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: recuperer un point
Bonjour,
Enfin, cela fonctionne très bien avec ta dernière solution, c'est à dire faire mon propre MapTool.
Encore un grand Merci pour ton aide et bonne journée
PYJ
Hors ligne
#10 Wed 24 January 2024 11:41
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: recuperer un point
Bonjour,
Content que ça fonctionne. C'est sur que dés que l'on a besoin de personnaliser les outils, il est plus efficace de les implémenter soi-même.
Bonne journée.
Hors ligne