#--------------------------------------------------------------------- # # Threading - A QGIS plugin to show an example of running code in # a thread from QGIS # # Copyright (C) 2009 Aaron Racicot # # EMAIL: aaronr (at) z-pulley.com # WEB : www.reprojected.com # #--------------------------------------------------------------------- # # licensed under the terms of GNU GPL 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # #--------------------------------------------------------------------- from PyQt4.QtCore import * from PyQt4.QtGui import * from qgis.core import * from qgis.gui import * import resources from threading_gui import Ui_Dialog import os import time class TestThread(QThread): def __init__(self, parentThread,parentObject): QThread.__init__(self, parentThread) self.parent = parentObject self.running = False self.total = 0 self.currentCount = 0 def loop(self): for i in xrange(0,10,1): self.emit(SIGNAL("runStatus(PyQt_PyObject)"),i) time.sleep(1) if self.running == False: print "(Printed from thread) Stop requested from QGIS" return False return True def run(self): self.running = True while (True): if not self.loop(): break self.emit(SIGNAL("runFinished(PyQt_PyObject)"),"Pass") def stop(self): self.running = False def getUpdate(self): return self.currentCount class ThreadingPlugin(QObject): def __init__(self, iface): QObject.__init__(self) # Save a reference to the QGIS iface self.iface = iface self.canvas = iface.mapCanvas() def initGui(self): # Create action self.action = QAction(QIcon(":/threading.png"), "Threading Example", self.iface.mainWindow()) self.action.setWhatsThis("Threading Example") QObject.connect(self.action, SIGNAL("activated()"), self.run) self.helpaction = QAction(QIcon(":/threadinghelp.png"), "About", self.iface.mainWindow()) self.helpaction.setWhatsThis("Threading Example Help") QObject.connect(self.helpaction, SIGNAL("activated()"), self.helprun) # Add to the main toolbar self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Threading", self.action) self.iface.addPluginToMenu("&Threading", self.helpaction) def unload(self): # Remove the plugin self.iface.removePluginMenu("&Threading",self.action) self.iface.removePluginMenu("&Threading",self.helpaction) self.iface.removeToolBarIcon(self.action) def helprun(self): # print "Help pressed..." infoString = QString("Written by Aaron Racicot\naaronr@z-pulley.com\n") infoString = infoString.append("Company - http://www.z-pulley.com\n\n") infoString = infoString.append("Blog - http://www.reprojected.com\n\n") infoString = infoString.append("Source: http://svn.reprojected.com/") infoString = infoString.append("qgisplugins/trunk/threading_demo\n") infoString = infoString.append("TRAC: http://trac.reprojected.com/") infoString = infoString.append("qgisplugins\n") QMessageBox.information(self.iface.mainWindow(), "Threading Plugin About",infoString) def run(self): print "Run Pressed" flags = Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMaximizeButtonHint self.gui = ThreadingGui(self.iface,flags) self.gui.show() def finished(self,xy): pass class ThreadingGui(QDialog, Ui_Dialog): def __init__(self, iface, fl): QDialog.__init__(self, iface.mainWindow(), fl) self.iface = iface self.setupUi(self) self.progressBar.setRange(0,10) self.progressBar.setValue(0) self.running = False self.runThread = None def on_btnCancel_released(self): print "Shutting down thread - ", self.runThread if self.runThread: self.runThread.stop() self.running = False self.close() def on_pushButton_released(self): if self.running == True: print "Shutting down thread - ", self.runThread self.running = False # Stop everything self.runThread.stop() self.pushButton.setText(QString("Start")) self.progressBar.setValue(0) else: self.running = True self.pushButton.setText(QString("Stop")) # Start it up... self.runThread = TestThread(self.iface.mainWindow(),self) print "Starting up thread - ", self.runThread # Use this signal from the thread to indicate the thread exited QObject.connect(self.runThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread) QObject.connect(self.runThread, SIGNAL("runStatus(PyQt_PyObject)"), self.runStatusFromThread) QObject.connect(self.runThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) self.runThread.start() # Testing code #print "Current priority is - ", self.thread().priority() #print "Current thread priority is - ", self.runThread.priority() #print "Current mainwindow priority is - ", self.iface.getMainWindow().thread().priority() print "Starting up a timer to let the thread run" self.timer = QTimer() QObject.connect(self.timer, SIGNAL("timeout()"), self.runStatus) self.timer.start(10) def runStatus(self): # print "runStatus recieved" self.runThread.msleep(1) def runFinishedFromThread(self,success): # print "Thread Finished with success = ", success self.timer.stop() def runStatusFromThread(self,statusMessage): # Fill in the updates to the progress bar and number display self.progressBar.setValue(statusMessage) def runErrorFromThread(self,errorMessage): print "Error recieved from thread = ", errorMessage