Lấy khoảng cách từ Công cụ đo lường QGIS?


13

Tôi đã xây dựng một plugin để cung cấp cơ sở dữ liệu Spatialite với mặt nạ đầu vào. Có hai trường đại diện cho kích thước tối thiểu / tối đa của một đối tượng.

Trong khoảnh khắc tôi gọi Công cụ đo lường ( iface.actionMeasure().trigger()) bằng hai "Nút đo", bấm vào thứ nguyên và nhập giá trị bằng bàn phím của tôi vào các trường (QLineEdit).

Có khả năng là sau khi tôi nhấp chuột phải (đo kết thúc) với Công cụ đo lường, giá trị sẽ được tự động cam kết với trường (tối thiểu hoặc tối đa, QLineEdit) không?

  1. Gọi công cụ đo lường (nó hoạt động)
  2. Nhấp chuột trái: bắt đầu đo
  3. và 4. cùng một lúc: Nhấp chuột phải và cam kết Tổng giá trị của Công cụ đo lường vào trường tối thiểu (QLineEdit).

nhập mô tả hình ảnh ở đây

CẬP NHẬT 1:

Một ngày sau khi hỏi câu hỏi này, tôi đã có ý tưởng để có một lớp linestring mà tôi có thể sử dụng làm công cụ đo lường (ST_Lpm (geom)). Ưu điểm là bạn có thể có toàn quyền kiểm soát thao tác và lấy dữ liệu từ nó. Một bất lợi là một lớp bổ sung trong dự án.

Một quy trình công việc có thể là:

  1. nhấp vào biện pháp: chuyển đổi chỉnh sửa, kích hoạt "Thêm tính năng"

  2. Tạo linestring đại diện cho kích thước tối thiểu của một đối tượng

  3. Xác nhận thay đổi, tính toán độ dài của linestring (ST_Lpm (geom)), cam kết độ dài với QLineEdit

  4. Đóng hộp thoại và xóa linestring (XÓA TỪ)

Nhưng câu hỏi thực tế của tôi vẫn còn. Có cách nào để lấy giá trị khoảng cách từ Công cụ đo trực tiếp không?

Cập nhật 2:

Với sự giúp đỡ nếu Jakob tôi có thể cập nhật QLineEdit của mình với Tổng giá trị của Công cụ đo cho đến khi tôi đóng Công cụ đo. Sau đó, giá trị được đặt thành '0,000 m'. Tôi đã giải quyết vấn đề này bằng cách sử dụng:

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

Nó hoạt động, nhưng tôi không biết nếu đây là một giải pháp thích hợp.

Câu trả lời:


10
  1. Tìm tiện ích QssMeasureBase
  2. Tìm QLineEdit với tổng giá trị trong tiện ích
  3. Kết nối một khe với tín hiệu thay đổi văn bản QLineEdit.

Mã này sẽ giúp bạn đi:

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

Để demo, các giá trị đo được ghi vào Bảng thông báo nhật ký trong một tab được gọi là kiểm tra. Thay vào đó, bạn cập nhật tối thiểu và tối đa QLineEdit.

nhập mô tả hình ảnh ở đây

Trên thực tế mã có thể được rút ngắn. Vòng lặp for ở trên là vì tôi không biết tên của tiện ích QssMeasureBase và phải xem tất cả các tiện ích cho văn bản 'đo'.

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

1
Trả lời tốt đẹp, tôi không phải là một lập trình viên nhưng tôi hiểu logic này. Làm tốt.
Mapperz

Tôi có thể kết nối giá trị 'editTotal' với QLineEdit của tôi, thành công. Nhưng khi tôi đóng hộp thoại QssMeasureBase, giá trị (QLineEdit) được đặt thành 0. Làm cách nào tôi có thể tránh điều này khi đóng hộp thoại?
Stefan

Khi tôi in tất cả các phần tử con của hộp thoại QssMeasureBase bằng: widget_measure = [w for w in QApplication.instance().allWidgets() if w.objectName() == 'QgsMeasureBase'][0]sau đó for i in widget_measure.children(): print i.objectName(), có tiện ích 'buttonBox', mà tôi hy vọng sẽ bao gồm nút này QDialogButtonBox.Close. Điều này có thể được sử dụng để nói "nếu đóng được bấm giữ giá trị editTotal hoặc không làm gì"?
Stefan

Vấn đề là tín hiệu văn bản được gọi trước khi tín hiệu từ chối. Bạn có thể kiểm tra nó bằng cách thêm: buttonbox = widget_measure.findChild (QĐialogButtonBox, 'buttonBox')
Jakob

Bạn có thể lưu trữ độ dài đo trong khe text_changed trong một mảng và sau đó trên khe từ chối chọn giá trị được nhập cuối cùng thứ hai trong mảng cho bạn gui.
Jakob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.