|
| 1 | +""" |
| 2 | +QGIS utilities module |
| 3 | +
|
| 4 | +""" |
| 5 | + |
| 6 | +from PyQt4.QtCore import QCoreApplication |
| 7 | +import sys |
| 8 | +import traceback |
| 9 | + |
| 10 | + |
| 11 | +####################### |
| 12 | +# ERROR HANDLING |
| 13 | + |
| 14 | +def showException(type, value, tb, msg): |
| 15 | + lst = traceback.format_exception(type, value, tb) |
| 16 | + if msg == None: |
| 17 | + msg = QCoreApplication.translate('Python', 'An error has occured while executing Python code:') |
| 18 | + txt = '<font color="red">%s</font><br><br>' % msg |
| 19 | + for s in lst: |
| 20 | + txt += s |
| 21 | + txt += '<br>%s<br>%s<br><br>' % (QCoreApplication.translate('Python','Python version:'), sys.version) |
| 22 | + txt += '%s %s' % (QCoreApplication.translate('Python','Python path:'), str(sys.path)) |
| 23 | + txt = txt.replace('\n', '<br>') |
| 24 | + txt = txt.replace(' ', ' ') # preserve whitespaces for nicer output |
| 25 | + |
| 26 | + from qgis.core import QgsMessageOutput |
| 27 | + msg = QgsMessageOutput.createMessageOutput() |
| 28 | + msg.setTitle(QCoreApplication.translate('Python', 'Python error')) |
| 29 | + msg.setMessage(txt, QgsMessageOutput.MessageHtml) |
| 30 | + msg.showMessage() |
| 31 | + |
| 32 | +def qgis_excepthook(type, value, tb): |
| 33 | + showException(type, value, tb, None) |
| 34 | + |
| 35 | +def installErrorHook(): |
| 36 | + sys.excepthook = qgis_excepthook |
| 37 | + |
| 38 | +def uninstallErrorHook(): |
| 39 | + sys.excepthook = sys.__excepthook__ |
| 40 | + |
| 41 | +# install error hook() on module load |
| 42 | +installErrorHook() |
| 43 | + |
| 44 | +# initialize 'iface' object |
| 45 | +iface = None |
| 46 | + |
| 47 | +def initInterface(pointer): |
| 48 | + from qgis.gui import QgisInterface |
| 49 | + from sip import wrapinstance |
| 50 | + global iface |
| 51 | + iface = wrapinstance(pointer, QgisInterface) |
| 52 | + |
| 53 | + |
| 54 | +####################### |
| 55 | +# CONSOLE OUTPUT |
| 56 | + |
| 57 | +old_stdout = sys.stdout |
| 58 | +console_output = None |
| 59 | + |
| 60 | +# hook for python console so all output will be redirected |
| 61 | +# and then shown in console |
| 62 | +def console_displayhook(obj): |
| 63 | + console_output = obj |
| 64 | + |
| 65 | +class QgisOutputCatcher: |
| 66 | + def __init__(self): |
| 67 | + self.data = '' |
| 68 | + def write(self, stuff): |
| 69 | + self.data += stuff |
| 70 | + def get_and_clean_data(self): |
| 71 | + tmp = self.data |
| 72 | + self.data = '' |
| 73 | + return tmp |
| 74 | + |
| 75 | +def installConsoleHooks(): |
| 76 | + sys.displayhook = console_displayhook |
| 77 | + sys.stdout = QgisOutputCatcher() |
| 78 | + |
| 79 | +def uninstallConsoleHooks(): |
| 80 | + sys.displayhook = sys.__displayhook__ |
| 81 | + sys.stdout = old_stdout |
| 82 | + |
| 83 | + |
| 84 | +####################### |
| 85 | +# PLUGINS |
| 86 | + |
| 87 | +# dictionary of plugins |
| 88 | +plugins = {} |
| 89 | + |
| 90 | +def pluginMetadata(packageName, fct): |
| 91 | + """ fetch metadata from a plugin """ |
| 92 | + try: |
| 93 | + package = sys.modules[packageName] |
| 94 | + return getattr(package, fct)() |
| 95 | + except: |
| 96 | + return "__error__" |
| 97 | + |
| 98 | +def loadPlugin(packageName): |
| 99 | + """ load plugin's package and ensure that plugin is reloaded when changed """ |
| 100 | + |
| 101 | + try: |
| 102 | + __import__(packageName) |
| 103 | + return True |
| 104 | + except: |
| 105 | + pass # continue... |
| 106 | + |
| 107 | + # snake in the grass, we know it's there |
| 108 | + sys.path_importer_cache.clear() |
| 109 | + |
| 110 | + # retry |
| 111 | + try: |
| 112 | + __import__(packageName) |
| 113 | + reload(packageName) |
| 114 | + return True |
| 115 | + except: |
| 116 | + msgTemplate = QCoreApplication.translate("Python", "Couldn't load plugin '%1' from ['%2']") |
| 117 | + msg = msgTemplate.arg(packageName).arg("', '".join(sys.path)) |
| 118 | + showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg) |
| 119 | + return False |
| 120 | + |
| 121 | + |
| 122 | +def startPlugin(packageName): |
| 123 | + """ initialize the plugin """ |
| 124 | + global plugins, iface |
| 125 | + |
| 126 | + package = sys.modules[packageName] |
| 127 | + |
| 128 | + errMsg = QCoreApplication.translate("Python", "Couldn't load plugin %1" ).arg(packageName) |
| 129 | + |
| 130 | + # create an instance of the plugin |
| 131 | + try: |
| 132 | + plugins[packageName] = package.classFactory(iface) |
| 133 | + except: |
| 134 | + msg = QCoreApplication.translate("Python", "%1 due an error when calling its classFactory() method").arg(errMsg) |
| 135 | + showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg) |
| 136 | + return False |
| 137 | + |
| 138 | + # initGui |
| 139 | + try: |
| 140 | + plugins[packageName].initGui() |
| 141 | + except: |
| 142 | + msg = QCoreApplication.translate("Python", "%1 due an error when calling its initGui() method" ).arg( errMsg ) |
| 143 | + showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg) |
| 144 | + return False |
| 145 | + |
| 146 | + return True |
| 147 | + |
| 148 | + |
| 149 | +def unloadPlugin(packageName): |
| 150 | + """ unload and delete plugin! """ |
| 151 | + global plugins |
| 152 | + |
| 153 | + try: |
| 154 | + plugins[packageName].unload() |
| 155 | + del plugins[packageName] |
| 156 | + return True |
| 157 | + except Exception, e: |
| 158 | + errMsg = QCoreApplication.translate("Python", "Error while unloading plugin %1").arg(packageName) |
| 159 | + showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg) |
| 160 | + return False |
0 commit comments