2

I would like to open a Plugin with the help of another Plugin.

Is it possible, if I want to switch the workflow of different plugins one after the other, that when I click the submit button of one plugin I close this plugin and another one opens automatically?

11
  • 1
    Do you have some code to show? Are those Plugins written by yourself or your intended to use some existing Plugins?
    – Taras
    May 3 '21 at 9:09
  • I dont think the code would help. It's just two plugins I wrote on myself and I want to open the second plugin when pressing the "OK"-button of the first one. May 3 '21 at 9:12
  • 1
    Yes, it is possible
    – Taras
    May 3 '21 at 9:13
  • 1
    When QGIS starts, it loads plugins as python modules. So, in your plugin, just create a method / function with import my_second_plugin and start it. May 6 '21 at 8:15
  • 1
    Just start your plugin as the method / function connected to the menu icon does. May 6 '21 at 8:21
7
+50

For my example, I took the QGIS plugin Plugin Builder 3 (link).

After install of this plugin, a new repository is made in :

\QGIS\QGIS3\profiles\default\python\plugins\pluginbuilder3

(here is the default profile default, it can be an other).

If you look in the __init__.py :

def classFactory(iface):
    """Load PluginBuilder class from file PluginBuilder.

    :param iface: A QGIS interface instance.
    :type iface: QgsInterface
    """
    from .plugin_builder import PluginBuilder
    return PluginBuilder(iface)

The classFactory function is a special method loaded at QGIS startup.

We see here it looks for the class PluginBuilder in the file plugin_builder.py.

In the PluginBuilder class definition, we look for the QGIS menu action :

class PluginBuilder:
    """A QGIS plugin that allows you to build QGIS plugins."""

    def __init__(self, iface):
[...]
    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # Create action that will start plugin configuration
        self.action = QAction(
            QIcon(':/plugins/plugin_builder/icon.png'),
            'Plugin Builder', self.iface.mainWindow())
        # connect the action to the run method
        self.action.triggered.connect(self.run)
[...]

The last line is the signal connection (callback) when the user clicks (or triggers) the menu action. It launch the method self.run.

So here you have two choices :

  • create in your plugin a method / function that call self.run
  • look in the self.run method what's going on and rewrite it in a method / function

First choice :

def open_other_plugin(self):
    from pluginbuilder3.plugin_builder import PluginBuilder

    self.new_plugin = PluginBuilder(self.iface)
    self.new_plugin.run()

self.open_other_plugin()

Second choice :

def open_other_plugin(self):
    from pluginbuilder3.plugin_builder_dialog import PluginBuilderDialog

    self.dialog = PluginBuilderDialog()
    self.dialog.setWindowTitle("My Builder Custom instance")
    self.dialog.show()

self.open_other_plugin()

We can also create a new dialog instance and return it (work in the two choices):

def create_other_plugin(self):
    from pluginbuilder3.plugin_builder_dialog import PluginBuilderDialog

    dialog = PluginBuilderDialog()
    return dialog

self.other_plugin = self.create_other_plugin()
self.other_plugin.show()

EDIT : Test

I've created two plugins plugin1 and plugin2. In the plugin folder of the current QGIS user profile :

  • plugin1

    • __init__.py
    • metadata.txt
  • plugin2

    • __init__.py
    • metadata.txt

First plugin, plugin1, that calls the second plugin

See the comments in the run method.

from PyQt5.QtWidgets import QAction, QMessageBox

def classFactory(iface):
    return FirstPlugin(iface)


class FirstPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.second_plugin = None

    def initGui(self):
        self.action = QAction("One", self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        self.iface.removeToolBarIcon(self.action)
        del self.action

    def run(self):
        # import plugin2 SecondPlugin class like other modules
        from plugin2 import SecondPlugin
        # create a second plugin class instance
        self.second_plugin = SecondPlugin(self.iface)
        QMessageBox.information(None, "First plugin", "This is the run of the first plugin")
        # call second plugin instance run method
        self.second_plugin.run()

Second plugin plugin2

This is a classic plugin, no special code here.

from PyQt5.QtWidgets import QAction, QDialog, QMessageBox

def classFactory(iface):
    return SecondPlugin(iface)


class SecondPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.dlg = QDialog()

    def initGui(self):
        self.action = QAction("Two", self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        self.iface.removeToolBarIcon(self.action)
        del self.action

    def run(self):
        QMessageBox.information(None, "Second plugin", "This is the run of the second plugin")
        self.dlg.show()
13
  • 1
    Is your plugin standalone or under QGIS ? May 14 '21 at 9:32
  • 1
    @MoritzSproll: I will test it with 2 minimal plugins. May 18 '21 at 7:13
  • 1
    @MoritzSproll: I've been buzy these days, I will look for a solution maybe today ... May 25 '21 at 7:54
  • 1
    @MoritzSproll: see my edit. May 26 '21 at 6:43
  • 1
    @MoritzSproll: I added a dialog in the example, hope that helps. May 26 '21 at 18:07
-1

First you need to check the plugin name in QGIS PYTHON console:

qgis.utils.plugins

In your plugin put this code:

import qgis        
secondPlugin = qgis.utils.plugins["PluginName"] # plugin instance
if secondPlugin
   secondPlugin.run() # Run plugin
2
  • Please provide detailed instructions with your answer. Explain what your code does, why it's needed, and what to do after running your code.
    – Midavalo
    Jan 4 at 23:01
  • Thanks for the answer. But, that run method doesn't run the plugin. It runs the run method if a run method exist in the plugin's root class. And you cannot be 100% sure if it exists. For example, QuickWKT plugin has no run method. Jan 5 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.