Skip to content
Permalink
Browse files

reimplemented unthreaded executino (threads are not still fully stabl…

…e). Running algs in a thread is now optional

git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@273 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
  • Loading branch information
volayaf
volayaf committed Jun 29, 2012
1 parent 201d347 commit f4b0df4936356378851f610811d6221188e50387
@@ -21,6 +21,8 @@
from sextante.pymorph.PymorphAlgorithmProvider import PymorphAlgorithmProvider
from sextante.mmqgisx.MMQGISXAlgorithmProvider import MMQGISXAlgorithmProvider
from sextante.lidar.LidarToolsAlgorithmProvider import LidarToolsAlgorithmProvider
from sextante.gui.UnthreadedAlgorithmExecutor import UnthreadedAlgorithmExecutor,\
SilentProgress

class Sextante:

@@ -287,18 +289,21 @@ def runalg(name, *args):
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, alg.getAsCommand())

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
algEx = AlgorithmExecutor(alg)
def finish():
#SextantePostprocessing.handleAlgorithmResults(alg)
QApplication.restoreOverrideCursor()
def error(msg):
QApplication.restoreOverrideCursor()
print msg
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
algEx.error.connect(error)
algEx.finished.connect(finish)
algEx.start()
algEx.wait()
if SextanteConfig.getSetting(SextanteConfig.USE_THREADS):
algEx = AlgorithmExecutor(alg)
def finish():
QApplication.restoreOverrideCursor()
def error(msg):
QApplication.restoreOverrideCursor()
print msg
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
algEx.error.connect(error)
algEx.finished.connect(finish)
algEx.start()
algEx.wait()
else:
UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress())

return alg.getOutputValuesAsDictionary()


@@ -350,19 +355,23 @@ def runandload(name, *args):
if msg:
QMessageBox.critical(None, "Unable to execute algorithm", msg)
return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
algEx = AlgorithmExecutor(alg)
def finish():
SextantePostprocessing.handleAlgorithmResults(alg)
QApplication.restoreOverrideCursor()
def error(msg):
QApplication.restoreOverrideCursor()
QMessageBox.critical(None, "Error", msg)
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
algEx.error.connect(error)
algEx.finished.connect(finish)
algEx.start()
if SextanteConfig.getSetting(SextanteConfig.USE_THREADS):
algEx = AlgorithmExecutor(alg)
def finish():
SextantePostprocessing.handleAlgorithmResults(alg)
QApplication.restoreOverrideCursor()
def error(msg):
QApplication.restoreOverrideCursor()
QMessageBox.critical(None, "Error", msg)
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
algEx.error.connect(error)
algEx.finished.connect(finish)
algEx.start()
else:
if UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress()):
SextantePostprocessing.handleAlgorithmResults(alg)




@@ -14,6 +14,7 @@ class SextanteConfig():
USE_SELECTED = "USE_SELECTED"
USE_FILENAME_AS_LAYER_NAME = "USE_FILENAME_AS_LAYER_NAME"
KEEP_DIALOG_OPEN = "KEEP_DIALOG_OPEN"
USE_THREADS = "USE_THREADS"

settings = {}
settingIcons= {}
@@ -22,6 +23,7 @@ class SextanteConfig():
def initialize():
icon = QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")
SextanteConfig.settingIcons["General"] = icon
SextanteConfig.addSetting(Setting("General", SextanteConfig.USE_THREADS, "Run algorithms in a new thread (still unstable)", False))
SextanteConfig.addSetting(Setting("General", SextanteConfig.KEEP_DIALOG_OPEN, "Keep dialog open after running an algorithm", False))
SextanteConfig.addSetting(Setting("General", SextanteConfig.USE_SELECTED, "Use only selected features in external applications", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.TABLE_LIKE_PARAM_PANEL, "Show table-like parameter panels", False))
@@ -15,8 +15,10 @@
from sextante.gui.AlgorithmExecutor import AlgorithmExecutor
from sextante.outputs.OutputHTML import OutputHTML
from sextante.core.SextanteResults import SextanteResults
from sextante.gui.ResultsDialog import ResultsDialog
from sextante.core.SextanteLog import SextanteLog
from sextante.core.SextanteConfig import SextanteConfig
from sextante.gui.UnthreadedAlgorithmExecutor import SilentProgress,\
UnthreadedAlgorithmExecutor

class BatchProcessingDialog(QtGui.QDialog):
def __init__(self, alg):
@@ -101,10 +103,23 @@ def okPressed(self):

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.progress.setMaximum(len(self.algs))
self.progress.setValue(0)
self.nextAlg(0)

self.table.setEnabled(False)
if SextanteConfig.getSetting(SextanteConfig.USE_THREADS):
self.progress.setValue(0)
self.nextAlg(0)
else:
i=1
self.progress.setMaximum(len(self.algs))
for alg in self.algs:
if UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress()):
self.progress.setValue(i)
self.loadHTMLResults(alg, i)
i+=1
else:
QApplication.restoreOverrideCursor()
return

self.finishAll()

def loadHTMLResults(self, alg, i):
for out in alg.outputs:
@@ -29,6 +29,7 @@
from sextante.outputs.OutputTable import OutputTable
from sextante.core.WrongHelpFileException import WrongHelpFileException
import os
from sextante.gui.UnthreadedAlgorithmExecutor import UnthreadedAlgorithmExecutor

try:
_fromUtf8 = QtCore.QString.fromUtf8
@@ -177,19 +178,28 @@ def accept(self):
self.progress.setMaximum(0)
self.progressLabel.setText("Processing algorithm...")
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
if iterateParam:
self.algEx = AlgorithmExecutor(self.alg, iterateParam)
useThread = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
if useThread:
if iterateParam:
self.algEx = AlgorithmExecutor(self.alg, iterateParam)
else:
command = self.alg.getAsCommand()
if command:
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, command)
self.algEx = AlgorithmExecutor(self.alg)
self.algEx.finished.connect(self.finish)
self.algEx.error.connect(self.error)
self.algEx.percentageChanged.connect(self.setPercentage)
self.algEx.textChanged.connect(self.setText)
self.algEx.start()
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(True)
else:
command = self.alg.getAsCommand()
if command:
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, command)
self.algEx = AlgorithmExecutor(self.alg)
self.algEx.finished.connect(self.finish)
self.algEx.error.connect(self.error)
self.algEx.percentageChanged.connect(self.setPercentage)
self.algEx.textChanged.connect(self.setText)
self.algEx.start()
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(True)
if iterateParam:
UnthreadedAlgorithmExecutor.runalgIterating(self.alg, iterateParam, self)
else:
UnthreadedAlgorithmExecutor.runalg(self.alg, self)
self.finish()

else:
QMessageBox.critical(self.dialog, "Unable to execute algorithm", "Wrong or missing parameter values")

@@ -0,0 +1,76 @@
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from sextante.core.QGisLayers import QGisLayers
from sextante.core.SextanteUtils import SextanteUtils
from sextante.gui.SextantePostprocessing import SextantePostprocessing
import traceback

class UnthreadedAlgorithmExecutor:

@staticmethod
def runalg(alg, progress):
'''Executes a given algorithm, showing its progress in the progress object passed along.
Return true if everything went OK, false if the algorithm could not be completed'''
try:
alg.execute(progress)
return True
except GeoAlgorithmExecutionException, e :
QMessageBox.critical(None, "Error", e.msg)
return False
except Exception:
QMessageBox.critical(None, "Error", traceback.format_exc())
return False

@staticmethod
def runalgIterating(alg,paramToIter,progress):
#generate all single-feature layers
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
layerfile = alg.getParameterValue(paramToIter)
layer = QGisLayers.getObjectFromUri(layerfile, False)
provider = layer.dataProvider()
allAttrs = provider.attributeIndexes()
provider.select( allAttrs )
feat = QgsFeature()
filelist = []
outputs = {}
while provider.nextFeature(feat):
output = SextanteUtils.getTempFilename("shp")
filelist.append(output)
writer = QgsVectorFileWriter(output, systemEncoding,provider.fields(), provider.geometryType(), provider.crs() )
writer.addFeature(feat)
del writer

#store output values to use them later as basenames for all outputs
for out in alg.outputs:
outputs[out.name] = out.value

#now run all the algorithms
i = 1
for f in filelist:
alg.setParameterValue(paramToIter, f)
for out in alg.outputs:
filename = outputs[out.name]
if filename:
filename = filename[:filename.rfind(".")] + "_" + str(i) + filename[filename.rfind("."):]
out.value = filename
progress.setText("Executing iteration " + str(i) + "/" + str(len(filelist)) + "...")
progress.setPercentage((i * 100) / len(filelist))
if UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress()):
SextantePostprocessing.handleAlgorithmResults(alg, False)
i+=1
else:
return False;

return True


class SilentProgress():

def setText(self, text):
pass

def setPercentage(self, i):
pass
@@ -364,7 +364,6 @@ def processAlgorithm(self, progress):
outputs[out.name] = out.value
self.producedOutputs[iAlg] = outputs
executed.append(iAlg)

except GeoAlgorithmExecutionException, e :
raise GeoAlgorithmExecutionException("Error executing algorithm " + str(iAlg) + "\n" + e.msg)
iAlg += 1
@@ -22,14 +22,16 @@ def __init__(self, alg=None):
self.setupUi()
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint |
QtCore.Qt.WindowMinMaxButtonsHint)
if alg:
if alg is not None:
self.alg = alg
self.textGroup.setText(alg.group)
self.textName.setText(alg.name)
self.repaintModel()
last = self.scene.getLastAlgorithmItem()
if last:
if last is not None:
self.view.ensureVisible(last)
else:
self.view.ensureVisible(0,0,10,10)
else:
self.alg = ModelerAlgorithm()
self.alg.setModelerView(self)

0 comments on commit f4b0df4

Please sign in to comment.
You can’t perform that action at this time.