QGIS gặp sự cố khi thực hiện khôi phục sau khi sửa đổi giá trị của tính năng do người dùng thêm với pyQGIS


8

Tôi đang phát triển một addon cho QGIS cần gán UUID cho bất kỳ tính năng nào ngay khi được thêm vào lớp. Tôi đang sử dụng tín hiệu Tính năng bổ sung để ghi UUID vào trường tương ứng của tính năng.

Đây là mã mà tôi đang sử dụng (càng đơn giản càng tốt):

def run(self):
    self.iface.mapCanvas().currentLayer().featureAdded.connect(self.onFeatureAdded)

def onFeatureAdded(self, fid):
    layer = self.iface.mapCanvas().currentLayer()
    layer.beginEditCommand("Set UUID")
    print layer.changeAttributeValue(fid, layer.fieldNameIndex('guid_pol'), 'some_random_uuid') # prints True
    layer.endEditCommand()

(Tôi đã tạo một plugin mới với bổ trợ 'Trình tạo plugin' và ở trên đó là mã duy nhất tôi đã thêm vào nó .)

Trừ khi tôi thiếu một cái gì đó, điều này tuân theo các hướng dẫn từ tài liệu trong sách hướng dẫn dành cho nhà phát triển của QGIS : http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/vector.html#modifying-vector-layers-with- an-chỉnh sửa-bộ đệm

Khi tôi chỉnh sửa lớp, nếu tôi thêm một tính năng, trường 'guide_pol' sẽ được đặt thành 'some_random_uuid' như mong đợi. Tuy nhiên, tôi có thể cam kết các thay đổi mà không gặp sự cố, nếu thay vì cam kết các thay đổi, tôi cố gắng hủy bỏ các sự cố QGIS với lỗi 0xC0000005 (Vi phạm truy cập) .

Thật thú vị, lệnh 'Đặt UUID' không được thêm vào ngăn xếp hoàn tác / làm lại (ít nhất, không phải vào Bảng điều khiển hoàn tác / làm lại ) và nếu tôi cũng cố gắng hoàn tác .

Tôi đang sử dụng QGIS 2.14 nhưng tôi đã quan sát hành vi tương tự với QGIS 2.12.

Tôi đang có một thời gian khó khăn để làm việc này. Có điều gì tôi đang làm sai?

Câu trả lời:


5

Tôi trả lời bản thân mình :-) Tôi đã tìm thấy một lời giải thích đây http://qgis-developer.osgeo.narkive.com/5wnziigA/wrapping-changeattributevalue-between-begin-and-end-editcommand#post2

Hiện tại không an toàn để thực hiện các cuộc gọi sửa đổi dữ liệu lớp vectơ trong các khe được kết nối với các tín hiệu thông báo về thay đổi dữ liệu (chẳng hạn như FeatureAdded). Vấn đề là tại thời điểm khi các tín hiệu đó được phát ra, các lệnh hoàn tác bên dưới của chúng chưa được đẩy lên ngăn xếp, do đó thực hiện các lệnh gọi tiếp theo gây ra hỏng hóc của ngăn xếp (lệnh hoàn tác cho hoạt động tiếp theo được đặt trước thao tác đầu tiên).

Giải pháp của tôi bao gồm trì hoãn việc xử lý bổ sung tính năng bằng cách sử dụng khe editCommandEnded. Đây là mã có liên quan:

def onFeatureAdded(self, fid):
    if fid < 0:
        self._addedFeatures.append(fid)

def onEditCommandEnded(self):
    while self._addedFeatures:
        fid = self._addedFeatures.pop()
        self._handleAdded(fid)

def _handleAdded(self, fid):
    guid_pol = str(uuid4()) # RFC 4122 UUID v4
    try:
        self.layer.beginEditCommand(u"Assign UUID")
        self.layer.changeAttributeValue(fid, self.layer.fieldNameIndex('guid_pol'), guid_pol)
        self.layer.endEditCommand()
    except:
        self.layer.destroyEditCommand()
        raise

Tôi hy vọng điều này sẽ giúp người khác.


3

mhm

Câu trả lời của bạn đã thực sự tuyệt vời và giải quyết vấn đề của chúng tôi ở đây. Nhưng để hiểu đầy đủ lý do tại sao điều này xảy ra tôi làm thế nào để giải quyết nó, tôi đã nghiên cứu mã nguồn của QGIS và đồng nghiệp của tôi và tôi đã làm một bài viết giải thích vấn đề một cách chi tiết. Xin vui lòng, hãy kiểm tra nó!

https://gis4programmer.wordpress.com/2017/02/26/usiness-properly-with-pyqgqis-edit-buffer-to-enable-undo-commands/


1
Ngay cả hôm nay với QGIS v3.4 tôi đã phải đối mặt với vấn đề này và bài đăng của bạn đã cho tôi một cách để giải quyết nó, cảm ơn vì đã đăng bài này! BTW, tôi đã nêu lên câu trả lời của bạn, giống như một năm trước hoặc lâu hơn: D
Germán Carrillo
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.