कीबोर्ड का उपयोग करते हुए, अनंत लूप की PyQGIS स्क्रिप्ट रोकना?


12

इसलिए मैंने एक स्क्रिप्ट लिखी, जो मुझे एक निश्चित समय अंतराल में "जबकि ट्रू:" का उपयोग करके बार-बार चाहिए (हर 5 सेकंड में time.sleep (5)) का उपयोग करके। अब तक बहुत अच्छा है, लेकिन जब मैं इसे रोकना चाहता हूं तो मैं नहीं कर सकता।

मैंने कंट्रोल + सी, कंट्रोल + ब्रेक, एस्केप की कोशिश की है और यह व्यावहारिक रूप से मेरे कीबोर्ड की उपेक्षा करता है। इसे रोकने का एकमात्र तरीका 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)

ऐसी कौन सी स्थितियाँ हैं, जिनसे 'निकास' को ट्रिगर किया जाना चाहिए?
निकलता है

1
qgis में एक ब्लॉकिंग प्रक्रिया को लागू करने के कई तरीके हैं। आप इसे Qt इवेंट लूप पर जाने के बिना नियंत्रण प्राप्त कर रहे हैं। मैं पता लगाने का सुझाव देता हूं: 1) एक घटना-संचालित वास्तुकला या 2 बनाएं) एक अजगर सबप्रोसेस या सिम्पल तरीके से अपनी प्रक्रिया का प्रबंधन करें) एक प्रोसेसिंग टूलबॉक्स स्क्रिप्ट बनाएं और यदि आवश्यक हो तो 2 के साथ एकीकृत करें
लुइगी पिरेली

3
दोस्तों शायद मैंने इसे गलत तरीका बताया। मुझे एक नए परिदृश्य के साथ प्रश्न को फिर से बताने दें: आप क्यूजीआईएस में पायथन कंसोल खोलते हैं, आप टाइप करते हैं: जबकि 1: "a" प्रिंट करें और आप एंटर दबाएं। फिर यह 'ए' को हमेशा-हमेशा के लिए छापता है। आप QGIS के बिना इसे कैसे रोक सकते हैं? यह सवाल और वास्तविक मुद्दा है
स्टेलिओस एम

यह एक सामान्य पायथन प्रश्न हो सकता है, इसलिए आपको StackOverflow पर उत्तर पाने के लिए बेहतर भाग्य प्राप्त हो सकता है।
मार्टिन

@ मार्टिन करेंगे। लेकिन यह एक बहुत ही अजीब सवाल है और यह मुझे हैरान करता है कि QGIS हेड डेवलपर्स ने अपने अजगर कंसोल में अनंत लूप परिदृश्य के बारे में सोचा था। यदि आप अपनी मशीन में 1: 'a' प्रिंट करते हैं, तो क्या आप इसे कीबोर्ड से रोक सकते हैं या यह मेरे सिस्टम की गलती है?
स्टेलियोस एम

जवाबों:


2

क्यूजीआईएस आपको अजगर की पूरी शक्ति प्रदान करता है। यह आश्चर्यजनक संभावनाएं खोलता है लेकिन संभावित नुकसान के साथ भी आता है। जो 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()

आप मुख्य विंडो पर ईवेंटफ़िल्टर () स्थापित कर सकते हैं यदि आपको इसकी आवश्यकता है तो कुंजी दबाएं।


0

चारों ओर एक काम के रूप में, आप एक रद्द बटन के साथ एक क्यूटी विजेट का उपयोग कर सकते हैं।

यह थोड़ा मोटा है, लेकिन यहाँ विजेट स्क्रिप्ट का उपयोग किया है:

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 पर संलग्न करना होगा) और फिर आप अपने लूप को रोकने के लिए रनिंग चर का उपयोग कर सकते हैं:

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

import cancel_widget

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

while btn.running:
    ...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.