Dừng tập lệnh PyQGIS có vòng lặp vô hạn, sử dụng bàn phím?


12

Vì vậy, tôi đã viết một kịch bản thực hiện những gì tôi muốn lặp đi lặp lại bằng cách sử dụng "while True:" trong một khoảng thời gian nhất định (cứ sau 5 giây sử dụng time.s ngủ (5)). Rất tốt, NHƯNG khi tôi muốn dừng nó, tôi không thể.

Tôi đã thử Control + C, Control + Break, Escape và nó thực tế bỏ qua bàn phím của tôi. Cách duy nhất để ngăn chặn nó là đóng QGIS. Có ý kiến ​​gì không? Hơn nữa, khi tập lệnh chạm vào time.s ngủ (5) loại độ trễ và đóng băng của QGIS trong 5 giây và tôi không thể, ví dụ, xoay lớp nhưng tôi cho rằng điều này là bình thường.

Đây là kịch bản của tôi:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from qgis.utils import iface
import time


while True: 

    def change_color():
        active_layer = iface.activeLayer()
        pipeline=[]
        txt=open('C:/users/stelios/desktop/project/Sensor.txt','r')
        for line in txt.readlines():
            pipeline.append(line.split())
        print pipeline 
        pipeline2=[]
        for label,color in pipeline:
            if "0" in color:
                pipeline2.append([label,"green"])
            else:
                pipeline2.append([label,"red"])

        print pipeline2
        elatomatikoi=""
        categories=[]

        for label,color in pipeline2:
            if 'red' in color:
                elatomatikoi=elatomatikoi + label+","
            symbol = QgsSymbolV2.defaultSymbol(active_layer.geometryType())
            symbol.setColor(QColor(color))
            category = QgsRendererCategoryV2(int(label), symbol, label)
            categories.append(category)

        expression = 'id' 
        renderer = QgsCategorizedSymbolRendererV2(expression, categories)
        active_layer.setRendererV2(renderer)
        active_layer.setCacheImage(None)
        iface.mapCanvas().refresh()
        iface.legendInterface().refreshLayerSymbology(active_layer)
        elatomatikoi= elatomatikoi[:-1]

        for label,color in pipeline2:
            if 'red' in color:
                QMessageBox.critical(None,"Warning",("Leakage at pipe(s):%s\nCheck Pipeline status " %elatomatikoi))
                break
        txt.close()

    change_color()
    time.sleep(5)

Các điều kiện nên kích hoạt một 'lối ra' là gì?
biệt danh

1
có nhiều cách để thực hiện quy trình chặn trong qgis. Bạn đang kiểm soát mà không để nó vào vòng lặp sự kiện Qt. Tôi đề nghị khám phá: 1) tạo kiến ​​trúc hướng sự kiện hoặc 2) quản lý quy trình của bạn trong quy trình con python hoặc cách mô phỏng) tạo tập lệnh Hộp công cụ xử lý và nếu cần tích hợp với lựa chọn 2
Luigi Pirelli

3
Các bạn có lẽ tôi đã nói sai. Hãy để tôi viết lại câu hỏi với một kịch bản mới: Bạn mở Bảng điều khiển Python trong QGIS, bạn nhập: while 1: in "a" và bạn nhấn enter. Sau đó, nó in 'a' mãi mãi. LÀM THẾ NÀO ĐỂ KIẾM ĐƯỢC MÀ KHÔNG CẦN THỰC HIỆN QGIS? Đó là câu hỏi và vấn đề thực sự
Stelios M

Đây có thể là một câu hỏi Python chung, vì vậy bạn có thể gặp may mắn hơn khi nhận được câu trả lời trên StackOverflow.
Martin

@Martin Sẽ làm. Nhưng đó là một câu hỏi khá khó hiểu và điều đó làm tôi ngạc nhiên khi các nhà phát triển đầu của QGIS chưa nghĩ đến kịch bản vòng lặp vô hạn trong bảng điều khiển python của họ. Nếu bạn thực thi trong khi 1: in 'a' trong máy của mình, bạn có thể dừng nó bằng bàn phím hay đó là lỗi hệ thống của tôi?
Stelios M

Câu trả lời:


2

QGIS cung cấp toàn bộ sức mạnh của trăn cho bạn. Điều này mở ra những khả năng tuyệt vời nhưng cũng đi kèm với những cạm bẫy tiềm năng. Điều này có thể làm cho QGIS không phản hồi, đóng băng hoặc thậm chí sụp đổ nó. Sử dụng nó một cách rộng rãi!

Trong trường hợp của bạn, thay vì gửi luồng chính đi ngủ trong 5 giây, tốt nhất bạn nên để QGIS làm việc khác (như nghe tiếng gõ phím hoặc nhấn nút) và đăng sự kiện hẹn giờ lên vòng lặp sự kiện chính sẽ đưa điều khiển quay lại kịch bản của bạn 5 giây sau.

Bạn có thể sử dụng ví dụ từ câu trả lời này như một điểm khởi đầu tốt. Để dừng nó, chỉ cần kết nối một số sự kiện với stop()khe cắm của bộ đếm thời gian.

def change_color():
    print('I am now red')

timer = QTimer()
timer.timeout.connect(change_color)
timer.start(5000)

someButton.clicked.connect(timer.stop)

Hoặc chỉ gọi nó bằng tay từ bảng điều khiển khi bạn nghĩ rằng đã đến lúc dừng nó

timer.stop()

Bạn cũng có thể cài đặt eventFilter () trên cửa sổ chính để chặn các lần nhấn phím nếu bạn cần.


0

Để giải quyết, bạn có thể sử dụng tiện ích QT với nút hủy.

Hơi khó hiểu một chút, nhưng đây là tập lệnh widget tôi đã sử dụng:

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setupUi(self)
        self.running = True
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(100, 100)
        self.horizontalLayout_3 = QtGui.QHBoxLayout(Form)
        self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.Cancel_btn = QtGui.QPushButton(Form)
        self.Cancel_btn.setMinimumSize(QtCore.QSize(0, 0))
        self.Cancel_btn.setMaximumSize(QtCore.QSize(425, 27))
        self.Cancel_btn.setObjectName(_fromUtf8("Cancel_btn"))
        self.horizontalLayout.addWidget(self.Cancel_btn)
        self.horizontalLayout_3.addLayout(self.horizontalLayout)
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Cancel", None))
        self.Cancel_btn.setText(_translate("Form", "Cancel", None))
        self.Cancel_btn.clicked.connect(self.Cancel)


    def Cancel(self):
        self.running = False

Điều này có thể được nhập vào tập lệnh pyQgis của bạn (bạn sẽ phải thêm thư mục vào sys.path) và sau đó bạn có thể sử dụng biến đang chạy để dừng vòng lặp while của mình:

import sys
sys.path.append("path/to/cancel_widget")

import cancel_widget

btn = cancel_widget.Ui_Form()
btn.show()

while btn.running:
    ...
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.