หยุดสคริปต์ PyQGIS ที่มีการวนซ้ำไม่สิ้นสุดโดยใช้แป้นพิมพ์ใช่หรือไม่


12

ดังนั้นฉันจึงเขียนสคริปต์ที่ทำสิ่งที่ฉันต้องการซ้ำแล้วซ้ำอีกโดยใช้ "ในขณะที่ True:" ในช่วงเวลาหนึ่ง (ทุก ๆ 5 วินาทีโดยใช้ time.sleep (5)) จนถึงตอนนี้ดีมาก แต่เมื่อฉันต้องการหยุดมันฉันก็ทำไม่ได้

ฉันได้ลอง Control + C, Control + Break, Escape แล้วก็ข้ามคีย์บอร์ดของฉันไป วิธีเดียวที่จะหยุดมันได้คือปิด QGIS ความคิดใด ๆ นอกจากนี้เมื่อสคริปต์เปิดใช้งาน time.sleep (5) ชนิด QGIS ของ lags และค้างเป็นเวลา 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

1
มีหลายวิธีที่จะใช้กระบวนการไม่มีการบล็อกใน qgis คุณได้รับการควบคุมโดยไม่ปล่อยให้มันวนซ้ำเหตุการณ์ Qt ฉันขอแนะนำให้สำรวจ: 1) สร้างสถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์หรือ 2) จัดการกระบวนการของคุณในกระบวนการย่อยของ python หรือวิธี simples) สร้างสคริปต์กล่องเครื่องมือการประมวลผลและหากจำเป็นต้องรวมกับตัวเลือก 2
Luigi Pirelli

3
ฉันอาจจะพูดว่ามันผิดไปแล้ว ผมขอใช้คำถามใหม่กับสถานการณ์ใหม่: คุณเปิด Python Console ใน QGIS คุณพิมพ์: ในขณะที่ 1: พิมพ์ "a" และคุณกด Enter จากนั้นจะพิมพ์ 'a' ตลอดไปและตลอดไป คุณจะหยุดมันได้อย่างไรโดยไม่ต้องออกจาก QGIS? นั่นคือคำถามและปัญหาที่แท้จริง
Stelios M

นี่อาจเป็นคำถาม Python ทั่วไปมากกว่าดังนั้นคุณอาจโชคดีกว่าที่จะได้รับคำตอบใน StackOverflow
มาร์ติน

@ มาร์ตินจะทำ แต่มันเป็นคำถามที่ค่อนข้างแปลกใจและมันก็ทำให้ฉันประหลาดใจว่าผู้พัฒนาหัว QGIS ไม่ได้คิดถึงสถานการณ์ลูปที่ไม่สิ้นสุดในคอนโซลหลามของพวกเขา หากคุณดำเนินการในขณะที่ 1: พิมพ์ '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) จากนั้นคุณสามารถใช้ตัวแปรการทำงานเพื่อหยุดขณะวนซ้ำ:

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.