Klavyeyi kullanarak sonsuz döngüye sahip PyQGIS betiği durduruluyor mu?


12

Bu yüzden belirli bir zaman aralığında (time.sleep (5) kullanarak her 5 saniyede bir) "while True:" kullanarak tekrar tekrar istediğimi yapan bir senaryo yazdım. Şimdiye kadar çok iyi, ama durdurmak istediğimde yapamam.

Control + C, Control + Break, Escape denedim ve pratik olarak klavyemi görmezden geliyor. Durdurmanın tek yolu QGIS'i kapatmaktır. Herhangi bir fikir? Ayrıca, script time.sleep (5) QGIS türünü vurur ve 5 saniye boyunca gecikme ve donma ve örneğin, katmanı pan olamaz ama bunun normal olduğunu varsayalım.

İşte benim senaryom:

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)

Bir 'çıkışı' tetiklemesi gereken koşullar nelerdir?
nickves

1
qgis'te engelleme yok sürecini uygulamanın birçok yolu vardır. Kontrolü Qt olay döngüsüne bırakmadan alıyorsunuz. Keşfedilmeyi öneririm: 1) olay odaklı bir mimari oluşturun veya 2) bir python alt işleminde veya basit bir şekilde sürecinizi yönetin) bir İşleme Araç Kutusu betiği oluşturun ve gerekirse seçim 2 ile entegrasyon
Luigi Pirelli

3
Çocuklar belki yanlış bir şekilde söyledim. Soruyu yeni bir senaryo ile yeniden ifade edeyim: Python Konsolu'nu QGIS'de açarsınız, şunu yazarsınız: 1: "a" yazdıysanız ve enter tuşuna basarsanız. Sonra sonsuza dek 'a' yazar. QGIS'den çıkmadan nasıl duruyorsunuz? Bu soru ve asıl mesele
Stelios M

Bu daha genel bir Python sorusu olabilir, bu nedenle StackOverflow'da yanıt almakta daha iyi şansınız olabilir.
Martin

@Martin Yapacak. Ama bu oldukça zor bir soru ve QGIS baş geliştiricilerinin python konsollarındaki sonsuz döngü senaryosunu düşünmemesini şaşırttı. 1: makinenize 'a' yazdıracaksanız, klavyeyle durdurabilir misiniz yoksa sistemimin hatası mı?
Stelios M

Yanıtlar:


2

QGIS size python'un tam gücünü sunar. Bu inanılmaz olasılıklar açar, ancak potansiyel tuzaklar ile birlikte gelir. Bu da QGIS'in tepkisiz kalmasına, donmasına ve hatta çökmesine neden olabilir. Akıllıca kullan!

Sizin durumunuzda, ana iş parçacığını 5 saniyeliğine uykuya göndermek yerine, QGIS'in başka bir şey yapmasına izin vermeniz (tuş vuruşlarını veya düğme basmalarını dinlemek gibi) ve ana olay döngüsüne kontrolü geri gönderecek bir zamanlayıcı olayı göndermeniz daha iyi olur betiğinizi 5 saniye sonra.

Bu cevaptaki örneği iyi bir başlangıç ​​noktası olarak kullanabilirsiniz. Durdurmak stop()için zamanlayıcı yuvasına bir olay bağlayın .

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

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

someButton.clicked.connect(timer.stop)

Veya durdurma zamanının geldiğini düşündüğünüzde sadece konsoldan manuel olarak arayın

timer.stop()

Gerekirse tuşlara basmak için ana pencereye eventFilter () de yükleyebilirsiniz .


0

Bir çözüm olarak, iptal düğmeli bir QT widget'ı kullanabilirsiniz.

Biraz kaba, ama kullandığım widget komut dosyası:

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

Bu, pyQgis betiğinize aktarılabilir (dizini sys.path dosyasına eklemeniz gerekir) ve ardından while değişkeninizi durdurmak için çalışan değişkeni kullanabilirsiniz:

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

import cancel_widget

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

while btn.running:
    ...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.