Tuesday, 9 May 2017

qgis - How to use Threads in PyQgis, mainly to keep UI active?


I'm trying to develop a plugin, which does heavy computations and as a result, user interface becomes inactive. I know that I should use threads to keep the UI alive (specifically, I have a progress bar that I want to update), but my experience with threads is very limited.


I was wondering if there are any good tutorials, or code snippets with documentation that cover this issue. sample of my code so far (without threads):


    def initGui(self):

# Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/lts/icon.png"),
u"LTS calculator", self.iface.mainWindow())
# connect the action to the run method
self.action.triggered.connect(self.run)

# Add toolbar button and menu item
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToMenu(u"<S Calculator", self.action)


# QtCore.QObject.connect(self.dlg.ui.find_cc, QtCore.SIGNAL("clicked()"), self.find_connected_components)

QtCore.QObject.connect(self.dlg.ui.process_Button,QtCore.SIGNAL("clicked()"), self.process)
# QtCore.QObject.connect(self.dlg.ui.layerCombo,QtCore.SIGNAL("currentIndexChanged(int)"), self.update_lts_field)
QtCore.QObject.connect(self.dlg.ui.layerCombo,QtCore.SIGNAL("activated (int)"), self.update_lts_field)
QtCore.QObject.connect(self.dlg.ui.find_cc_Button,QtCore.SIGNAL("clicked()"), self.find_connected_components)


self.update_ui()

self.layers = self.iface.legendInterface().layers() # store the layer list
# self.dlg.ui.layerCombo.clear() # clear the combo
for layer in self.layers: # foreach layer in legend
self.dlg.ui.layerCombo.addItem( layer.name() ) # add it t


def process(self):
""" Calculates Stress for the selected layer"""
index = self.dlg.ui.layerCombo.currentIndex()
if index < 0:

# it may occur if there's no layer in the combo/legend
pass
else:
layer = self.dlg.ui.layerCombo.itemData(index)
# layer = QgsVectorLayer(self.fileName, "layer_name", "ogr")
nFeat = layer.featureCount()
layer.startEditing()
...
street.compute_LTS()
if street.LTS != None :

i+=1
j=ceil(i/(nFeat/100))
self.dlg.ui.progress_bar.setValue(j)
layer.updateFeature(feature)
# run method that performs all the real work
def run(self):
# show the dialog
self.dlg.show()
self.dlg.ui.progress_bar.setValue(0)
self.dlg.ui.progressBar.setValue(0)

self.dlg.ui.layerCombo.clear()
self.dlg.ui.lts_combo.clear()

layers = QgsMapLayerRegistry.instance().mapLayers().values()
for layer in layers:
if layer.type() == QgsMapLayer.VectorLayer and layer.geometryType() == QGis.Line:
self.dlg.ui.layerCombo.addItem( layer.name(), layer )

self.update_lts_field()
# Run the dialog event loop

result = self.dlg.exec_()
# See if OK was pressed
if result == 1:
# do something useful (delete the line containing pass and
# substitute with your code)
pass

Thanks




No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...