키보드를 사용하여 무한 루프가있는 PyQGIS 스크립트를 중지 하시겠습니까?


12

그래서 특정 시간 간격 (time.sleep (5)을 사용하여 5 초마다)에서 "while True :"를 사용하여 반복적으로 원하는 것을 수행하는 스크립트를 작성했습니다. 지금까지는 좋았지 만 중지하고 싶을 때는 할 수 없습니다.

Control + C, Control + Break, Escape를 시도했지만 실제로 키보드를 무시합니다. 중지하는 유일한 방법은 QGIS를 닫는 것입니다. 어떤 아이디어? 또한 스크립트가 time.sleep (5) QGIS 종류의 지연을 발생시키고 5 초 동안 정지하면 예를 들어 레이어를 패닝 할 수 없지만 이것이 정상이라고 가정합니다.

내 스크립트는 다음과 같습니다.

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)

'종료'를 유발해야하는 조건은 무엇입니까?
nickves mar

1
qgis에서 비 차단 프로세스를 구현하는 방법에는 여러 가지가 있습니다. Qt 이벤트 루프에 그대로 두지 않고 컨트롤을 가져옵니다. 1) 이벤트 중심 아키텍처를 만들거나 2) 파이썬 하위 프로세스 또는 간단한 방법으로 프로세스를 관리합니다. Processing Toolbox 스크립트를 만들고 필요한 경우 선택 2
Luigi Pirelli

3
어쩌면 내가 잘못 말했을거야. QGIS에서 Python Console을 열고 다음과 같이 입력합니다. while 1 : print "a"를 입력하고 Enter 키를 누르십시오. 그런 다음 'a'를 영원히 그리고 영원히 인쇄합니다. QGIS를 중단하지 않고 어떻게 중단합니까? 이것이 바로 질문이자 실질적인 문제입니다.
Stelios M

이것은 일반적인 파이썬 질문 일 수 있으므로 StackOverflow에 대한 답변을 얻는 것이 더 좋을 것입니다.
Martin

@ 마틴 윌. 그러나 이것은 매우 어려운 질문이며 QGIS 헤드 개발자가 파이썬 콘솔에서 무한 루프 시나리오를 생각하지 않았다는 사실에 놀랍습니다. 컴퓨터에서 1 : print 'a'를 실행하는 동안 키보드로 키보드를 중지 할 수 있습니까? 아니면 시스템 오류입니까?
Stelios M

답변:


2

QGIS는 강력한 파이썬 기능을 제공합니다. 이것은 놀라운 가능성을 열어 주지만 잠재적 인 함정도 있습니다. QGIS가 응답하지 않거나 멈추거나 충돌 할 수 있습니다. 현명하게 사용하십시오!

귀하의 경우 메인 스레드를 5 초 동안 휴면 상태로 보내는 대신 QGIS가 키 스트로크 또는 버튼 누름 청취와 같은 다른 작업을 수행하고 타이머 이벤트를 메인 이벤트 루프에 게시하여 컨트롤을 다시 전달하는 것이 좋습니다. 5 초 후 스크립트

이 답변 의 예를 좋은 출발점으로 사용할 수 있습니다 . 중지하려면 일부 이벤트를 stop()타이머 슬롯에 연결하십시오.

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

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

someButton.clicked.connect(timer.stop)

또는 콘솔을 중지해야 할 때 콘솔에서 수동으로 호출하십시오.

timer.stop()

필요한 경우 키 누르기를 가로 채기 위해 기본 창에 eventFilter ()를 설치할 수도 있습니다 .


0

이 문제를 해결하기 위해 취소 단추가있는 QT 위젯을 사용할 수 있습니다.

조금 거칠지 만 여기에 내가 사용한 위젯 스크립트가 있습니다.

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

이것은 pyQgis 스크립트로 임포트 될 수 있으며 (디렉토리를 sys.path에 추가해야합니다) 그리고 running 변수를 사용하여 while 루프를 중지 할 수 있습니다 :

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

import cancel_widget

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

while btn.running:
    ...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.