Obtendo a distância da ferramenta QGIS Measure?

13

Eu construí um plugin para alimentar um banco de dados Spatialite com uma máscara de entrada. Existem dois campos que representam a dimensão mínima / máxima de um objeto.

No momento em que chamo a ferramenta Measure ( iface.actionMeasure().trigger()) com os dois botões de pressão "measure", clique na dimensão e digite o valor com o teclado nos campos (QLineEdit).

Existe a possibilidade de que, depois de clicar com o botão direito do mouse (concluir a medição) com a Ferramenta de Medição, o valor seja automaticamente confirmado no campo (mínimo ou máximo, QLineEdit)?

  1. Ferramenta Call Measure (funciona)
  2. Clique esquerdo: comece a medir
  3. e 4. de uma vez: Clique com o botão direito do mouse e confirme o valor total da ferramenta Measure no campo min (QLineEdit).

insira a descrição da imagem aqui

ATUALIZAÇÃO 1:

Um dia depois de fazer essa pergunta, tive a ideia de ter uma camada de cadeia de linhas que eu poderia usar como uma ferramenta de medida (ST_Length (geom)). A vantagem é que você pode ter o controle total da manipulação e obtenção de dados a partir dele. Uma desvantagem é uma camada adicional no projeto.

Um fluxo de trabalho pode ser:

  1. clique em medir: alterne a edição, ative "Adicionar recurso"

  2. Crie cadeia de linhas que represente a dimensão mínima de um objeto

  3. Confirme as alterações, calcule o comprimento da cadeia de linhas (ST_Length (geom)), confirme o comprimento para QLineEdit

  4. Feche a caixa de diálogo e remova a cadeia de linhas (DELETE FROM)

Mas minha pergunta real permanece. Existe uma maneira de obter o valor da distância diretamente da Ferramenta Medir?

Atualização 2:

Com a ajuda do Jakob, posso atualizar meu QLineEdit com o valor Total da ferramenta Measure até fechar a ferramenta Measure. Então o valor é definido como '0,000 m'. Resolvi esse problema usando o seguinte:

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

Funciona, mas não sei se é uma solução adequada.

Stefan
fonte

Respostas:

10
  1. Encontre o widget QgsMeasureBase
  2. Encontre o QLineEdit com o valor total no widget
  3. Conecte um slot ao sinal QLineEdit textChanged.

Este código deve ajudar você a:

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")

Para demonstração, os valores medidos são gravados no Painel de mensagens de log em uma guia chamada teste. Em vez disso, você atualiza o QLineEdit mínimo e máximo.

insira a descrição da imagem aqui

Na verdade, o código pode ser reduzido. O loop for acima foi porque eu não sabia o nome do widget QgsMeasureBase e tive que dar uma olhada em todos os widgets do texto 'measure'.

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
fonte
1
Resposta bacana, não sou programador, mas entendo essa lógica. Bem feito.
Mapperz
Consigo conectar o valor 'editTotal' ao meu QLineEdit com êxito. Mas quando fecho a caixa de diálogo QgsMeasureBase, o valor (QLineEdit) é definido como 0. Como posso evitar isso quando fecho a caixa de diálogo?
Stefan
Quando imprimo todos os filhos da caixa de diálogo QgsMeasureBase com: widget_measure = [w for w in QApplication.instance().allWidgets() if w.objectName() == 'QgsMeasureBase'][0]then for i in widget_measure.children(): print i.objectName(), existe o widget 'buttonBox', que espero inclua o botão QDialogButtonBox.Close. Isso pode ser usado para dizer "se clicar em fechar, mantenha o valor editTotal ou não faça nada"?
Stefan
O problema é que o sinal alterado de texto é chamado antes do sinal de rejeição. Você pode testá-lo adicionando: buttonbox = widget_measure.findChild (QDialogButtonBox, 'buttonBox') buttonbox.rejected.connect (buttonbox_rejected) com a função em cima: def buttonbox_rejected (): QgsMessageLog.logMessage ('rejeitado', "teste")
Jakob
Você pode armazenar o comprimento da medida no slot text_changed em uma matriz e, em seguida, no slot de rejeição, escolher o segundo último valor inserido na matriz para sua GUI.
Jakob