Obtenir la distance de l'outil de mesure QGIS?

13

J'ai construit un plugin pour alimenter une base de données Spatialite avec un masque de saisie. Il y a deux champs qui représentent la dimension min / max d'un objet.

Au moment où j'appelle l'outil de mesure ( iface.actionMeasure().trigger()) avec les deux boutons-poussoirs "mesure", cliquez sur la dimension et tapez la valeur avec mon clavier dans les champs (QLineEdit).

Existe-t-il la possibilité qu'après avoir fait le clic droit (terminer la mesure) avec l'outil Mesurer, la valeur sera automatiquement validée dans le champ (min ou max, QLineEdit)?

  1. Outil de mesure d'appel (cela fonctionne)
  2. Clic gauche: commencer à mesurer
  3. et 4. à la fois: clic droit et validation de la valeur totale de l'outil de mesure dans le champ min (QLineEdit).

entrez la description de l'image ici

MISE À JOUR 1:

Un jour après avoir posé cette question, j'ai eu l'idée d'avoir une couche de chaîne de lignes que je pourrais utiliser comme outil de mesure (ST_Length (geom)). L'avantage est que vous pouvez avoir le contrôle total de la manipulation et de l'obtention de données à partir de celui-ci. Un inconvénient est une couche supplémentaire dans le projet.

Un workflow pourrait être:

  1. cliquez sur mesure: basculez l'édition, activez "Ajouter une fonction"

  2. Créer une chaîne de lignes qui représente la dimension minimale d'un objet

  3. Confirmer les modifications, calculer la longueur de la chaîne de lignes (ST_Length (geom)), valider la longueur dans QLineEdit

  4. Fermer la boîte de dialogue et supprimer la chaîne de ligne (DELETE FROM)

Mais ma véritable question demeure. Existe-t-il un moyen d'obtenir directement la valeur de distance à partir de l'outil de mesure?

Mise à jour 2:

Avec l'aide de Jakob, je peux mettre à jour mon QLineEdit avec la valeur totale de l'outil de mesure jusqu'à ce que je ferme l'outil de mesure. Ensuite, la valeur est définie sur '0,000 m'. J'ai résolu ce problème en utilisant ceci:

def text_changed(str_measure):
    if str_measure == '0,000 m':
        pass
    else:
        self.min.setText(str_measure)

Cela fonctionne, mais je ne sais pas si c'est une bonne solution.

Stefan
la source

Réponses:

10
  1. Trouvez le widget QgsMeasureBase
  2. Trouvez le QLineEdit avec la valeur totale dans le widget
  3. Connectez un slot au signal textLhanged QLineEdit.

Ce code devrait vous permettre de démarrer:

def text_changed(str_measure):
        QgsMessageLog.logMessage(str_measure, "test")

from qgis.core import QgsMessageLog
from PyQt4.QtGui import QApplication, QLineEdit
from PyQt4.QtCore import pyqtSignal

QgsMessageLog.logMessage("start", "test")

for w in QApplication.instance().allWidgets():
    name = w.objectName()
    if name == 'QgsMeasureBase':
        QgsMessageLog.logMessage(name, "test")

        lineedit = w.findChild(QLineEdit, 'editTotal')
        QgsMessageLog.logMessage('Text: {}'.format(lineedit.text()),'test')

        #{object}.{signal}.connect({slot})
        lineedit.textChanged.connect(text_changed) 
        break

QgsMessageLog.logMessage("stop", "test")
QgsMessageLog.logMessage("", "test")

Pour la démonstration, les valeurs mesurées sont écrites dans le panneau des messages de journal dans un onglet appelé test. Au lieu de cela, vous mettez à jour votre QLineEdit min et max.

entrez la description de l'image ici

En fait, le code peut être raccourci. La boucle for ci-dessus était parce que je ne connaissais pas le nom du widget QgsMeasureBase et que je devais jeter un coup d'œil à tous les widgets du texte 'mesure'.

def text_changed(str_measure):
    QgsMessageLog.logMessage(str_measure, "test")

from qgis.core import QgsMessageLog
from PyQt4.QtGui import QApplication, QLineEdit
from PyQt4.QtCore import pyqtSignal

QgsMessageLog.logMessage("---start---", "test")

widget_measure = [w for w in QApplication.instance().allWidgets() if w.objectName() == 'QgsMeasureBase'][0]
lineedit = widget_measure.findChild(QLineEdit, 'editTotal')
lineedit.textChanged.connect(text_changed) 

QgsMessageLog.logMessage('Text: {}'.format(lineedit.text()),'test')

QgsMessageLog.logMessage("---stop---", "test")
Jakob
la source
1
Belle réponse, je ne suis pas programmeur mais je comprends cette logique. Bien joué.
Mapperz
Je peux connecter la valeur «editTotal» à mon QLineEdit, avec succès. Mais lorsque je ferme la boîte de dialogue QgsMeasureBase, la valeur (QLineEdit) est définie sur 0. Comment puis-je éviter cela lorsque je ferme la boîte de dialogue?
Stefan
Lorsque j'imprime tous les enfants de la boîte de dialogue QgsMeasureBase avec: widget_measure = [w for w in QApplication.instance().allWidgets() if w.objectName() == 'QgsMeasureBase'][0]puis for i in widget_measure.children(): print i.objectName(), il y a le widget 'buttonBox', qui j'espère inclut le bouton QDialogButtonBox.Close. Cela peut-il être utilisé pour dire "si vous cliquez sur Fermer, conservez la valeur editTotal ou ne faites rien"?
Stefan
Le problème est que le signal texte modifié est appelé avant le signal de rejet. Vous pouvez le tester en ajoutant: buttonbox = widget_measure.findChild (QDialogButtonBox, 'buttonBox') buttonbox.rejected.connect (buttonbox_rejected) avec la fonction en haut: def buttonbox_rejected (): QgsMessageLog.logMessage ('rejeté', "test")
Jakob
Pouvez-vous stocker la longueur de mesure dans l'emplacement text_changed dans un tableau, puis sur l'emplacement de rejet, choisissez l'avant-dernière valeur entrée dans le tableau pour votre gui.
Jakob