mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
Add Python utils method to start a Processing specific plugin
This command adds a plugin to active plugins and calls initProcessing(), initializing only Processing related components of that plugin. The new initProcessing() hook should be implemented by plugins which provide Processing providers or algorithm, and should only implement code which is required to load the provider and algorithms. Strictly no GUI related code should be used here, that MUST be moved out of initializers and deferred to the plugin's initGui implementation.
This commit is contained in:
parent
92b7356734
commit
2f82bab1d9
@ -314,8 +314,8 @@ def loadPlugin(packageName):
|
||||
return False
|
||||
|
||||
|
||||
def startPlugin(packageName):
|
||||
""" initialize the plugin """
|
||||
def _startPlugin(packageName):
|
||||
""" initializes a plugin, but does not load GUI """
|
||||
global plugins, active_plugins, iface, plugin_times
|
||||
|
||||
if packageName in active_plugins:
|
||||
@ -326,18 +326,30 @@ def startPlugin(packageName):
|
||||
|
||||
package = sys.modules[packageName]
|
||||
|
||||
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin '{0}'").format(packageName)
|
||||
|
||||
start = time.process_time()
|
||||
|
||||
# create an instance of the plugin
|
||||
try:
|
||||
plugins[packageName] = package.classFactory(iface)
|
||||
except:
|
||||
_unloadPluginModules(packageName)
|
||||
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin '{0}'").format(packageName)
|
||||
msg = QCoreApplication.translate("Python", "{0} due to an error when calling its classFactory() method").format(errMsg)
|
||||
showException(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], msg, messagebar=True)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _addToActivePlugins(packageName, duration):
|
||||
""" Adds a plugin to the list of active plugins """
|
||||
active_plugins.append(packageName)
|
||||
plugin_times[packageName] = "{0:02f}s".format(duration)
|
||||
|
||||
|
||||
def startPlugin(packageName):
|
||||
""" initialize the plugin """
|
||||
global plugins, active_plugins, iface, plugin_times
|
||||
start = time.process_time()
|
||||
if not _startPlugin(packageName):
|
||||
return False
|
||||
|
||||
# initGui
|
||||
try:
|
||||
@ -345,14 +357,43 @@ def startPlugin(packageName):
|
||||
except:
|
||||
del plugins[packageName]
|
||||
_unloadPluginModules(packageName)
|
||||
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin '{0}'").format(packageName)
|
||||
msg = QCoreApplication.translate("Python", "{0} due to an error when calling its initGui() method").format(errMsg)
|
||||
showException(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], msg, messagebar=True)
|
||||
return False
|
||||
|
||||
# add to active plugins
|
||||
active_plugins.append(packageName)
|
||||
end = time.process_time()
|
||||
plugin_times[packageName] = "{0:02f}s".format(end - start)
|
||||
_addToActivePlugins(packageName, end - start)
|
||||
return True
|
||||
|
||||
|
||||
def startProcessingPlugin(packageName):
|
||||
""" initialize only the Processing components of a plugin """
|
||||
global plugins, active_plugins, iface, plugin_times
|
||||
start = time.process_time()
|
||||
if not _startPlugin(packageName):
|
||||
return False
|
||||
|
||||
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin '{0}'").format(packageName)
|
||||
if not hasattr(plugins[packageName], 'initProcessing'):
|
||||
del plugins[packageName]
|
||||
_unloadPluginModules(packageName)
|
||||
msg = QCoreApplication.translate("Python", "{0} - plugin has no initProcessing() method").format(errMsg)
|
||||
showException(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], msg, messagebar=True)
|
||||
return False
|
||||
|
||||
# initProcessing
|
||||
try:
|
||||
plugins[packageName].initProcessing()
|
||||
except:
|
||||
del plugins[packageName]
|
||||
_unloadPluginModules(packageName)
|
||||
msg = QCoreApplication.translate("Python", "{0} due to an error when calling its initProcessing() method").format(errMsg)
|
||||
showException(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], msg, messagebar=True)
|
||||
return False
|
||||
|
||||
end = time.process_time()
|
||||
_addToActivePlugins(packageName, end - start)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -161,6 +161,16 @@ class PYTHON_EXPORT QgsPythonUtils
|
||||
*/
|
||||
virtual bool startPlugin( const QString &packageName ) = 0;
|
||||
|
||||
/**
|
||||
* Start a Processing plugin
|
||||
*
|
||||
* This command adds a plugin to active plugins and calls initProcessing(),
|
||||
* initializing only Processing related components of that plugin.
|
||||
*
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
virtual bool startProcessingPlugin( const QString &packageName ) = 0;
|
||||
|
||||
/**
|
||||
* Helper function to return some information about a plugin.
|
||||
*
|
||||
|
@ -623,6 +623,13 @@ bool QgsPythonUtilsImpl::startPlugin( const QString &packageName )
|
||||
return ( output == QLatin1String( "True" ) );
|
||||
}
|
||||
|
||||
bool QgsPythonUtilsImpl::startProcessingPlugin( const QString &packageName )
|
||||
{
|
||||
QString output;
|
||||
evalString( "qgis.utils.startProcessingPlugin('" + packageName + "')", output );
|
||||
return ( output == QLatin1String( "True" ) );
|
||||
}
|
||||
|
||||
bool QgsPythonUtilsImpl::canUninstallPlugin( const QString &packageName )
|
||||
{
|
||||
QString output;
|
||||
|
@ -85,6 +85,7 @@ class QgsPythonUtilsImpl : public QgsPythonUtils
|
||||
QStringList listActivePlugins() override;
|
||||
bool loadPlugin( const QString &packageName ) override;
|
||||
bool startPlugin( const QString &packageName ) override;
|
||||
bool startProcessingPlugin( const QString &packageName ) override;
|
||||
QString getPluginMetadata( const QString &pluginName, const QString &function ) override;
|
||||
bool canUninstallPlugin( const QString &packageName ) override;
|
||||
bool unloadPlugin( const QString &packageName ) override;
|
||||
|
@ -40,6 +40,9 @@ class TestQgisAppPython : public QObject
|
||||
void init() {} // will be called before each testfunction is executed.
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
|
||||
void hasPython();
|
||||
void plugins();
|
||||
void pythonPlugin();
|
||||
void runString();
|
||||
void evalString();
|
||||
|
||||
@ -53,6 +56,8 @@ TestQgisAppPython::TestQgisAppPython() = default;
|
||||
//runs before all tests
|
||||
void TestQgisAppPython::initTestCase()
|
||||
{
|
||||
qputenv( "QGIS_PLUGINPATH", QByteArray( TEST_DATA_DIR ) + "/test_plugin_path" );
|
||||
|
||||
// Set up the QgsSettings environment
|
||||
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
|
||||
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
|
||||
@ -73,6 +78,33 @@ void TestQgisAppPython::cleanupTestCase()
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgisAppPython::hasPython()
|
||||
{
|
||||
QVERIFY( mQgisApp->mPythonUtils->isEnabled() );
|
||||
}
|
||||
|
||||
void TestQgisAppPython::plugins()
|
||||
{
|
||||
QVERIFY( mQgisApp->mPythonUtils->pluginList().contains( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( !mQgisApp->mPythonUtils->isPluginLoaded( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->listActivePlugins().isEmpty() );
|
||||
// load plugin
|
||||
QVERIFY( !mQgisApp->mPythonUtils->unloadPlugin( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->loadPlugin( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( !mQgisApp->mPythonUtils->isPluginLoaded( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->startPlugin( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->isPluginLoaded( QStringLiteral( "PluginPathTest" ) ) );
|
||||
QCOMPARE( mQgisApp->mPythonUtils->listActivePlugins(), QStringList() << QStringLiteral( "PluginPathTest" ) );
|
||||
}
|
||||
|
||||
void TestQgisAppPython::pythonPlugin()
|
||||
{
|
||||
QVERIFY( mQgisApp->mPythonUtils->pluginList().contains( QStringLiteral( "ProcessingPluginTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->loadPlugin( QStringLiteral( "ProcessingPluginTest" ) ) );
|
||||
QVERIFY( mQgisApp->mPythonUtils->startProcessingPlugin( QStringLiteral( "ProcessingPluginTest" ) ) );
|
||||
QVERIFY( !mQgisApp->mPythonUtils->startProcessingPlugin( QStringLiteral( "PluginPathTest" ) ) );
|
||||
}
|
||||
|
||||
void TestQgisAppPython::runString()
|
||||
{
|
||||
QVERIFY( mQgisApp->mPythonUtils->runString( "a=1+1" ) );
|
||||
@ -91,5 +123,6 @@ void TestQgisAppPython::evalString()
|
||||
QVERIFY( !mQgisApp->mPythonUtils->evalString( "1+", result ) );
|
||||
}
|
||||
|
||||
|
||||
QGSTEST_MAIN( TestQgisAppPython )
|
||||
#include "testqgisapppython.moc"
|
||||
|
45
tests/testdata/test_plugin_path/ProcessingPluginTest/__init__.py
vendored
Normal file
45
tests/testdata/test_plugin_path/ProcessingPluginTest/__init__.py
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
__init__.py
|
||||
---------------------
|
||||
Date : July 2013
|
||||
Copyright : (C) 2013 by Hugo Mercier
|
||||
Email : hugo dot mercier at oslandia dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Hugo Mercier'
|
||||
__date__ = 'July 2013'
|
||||
__copyright__ = '(C) 2013, Hugo Mercier'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class Test:
|
||||
|
||||
def __init__(self, iface):
|
||||
pass
|
||||
|
||||
def initGui(self):
|
||||
assert False
|
||||
|
||||
def initProcessing(self):
|
||||
pass
|
||||
|
||||
def unload(self):
|
||||
pass
|
||||
|
||||
def classFactory(iface):
|
||||
# load Test class from file Test
|
||||
return Test(iface)
|
7
tests/testdata/test_plugin_path/ProcessingPluginTest/metadata.txt
vendored
Normal file
7
tests/testdata/test_plugin_path/ProcessingPluginTest/metadata.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
[general]
|
||||
name=plugin path test
|
||||
qgisMinimumVersion=2.0
|
||||
description=desc
|
||||
version=0.1
|
||||
author=HM/Oslandia
|
||||
email=hugo.mercier@oslandia.com
|
Loading…
x
Reference in New Issue
Block a user