How can I add a second Toolbar Button and Dialog to a QGIS plugin built with Plugin Builder?

1. Use Plugin builder to create a new plugin

The files created are shown in the following picture

enter image description here

2. Convert the resources file (resources.qrc) to Python file (resources.py) using the OSGeo4W Shell

pyrcc4 -o resources_rc.py resources.qrc

After that, if you look inside the plugin folder, you will notice a new .py file, the resources.py file that was just created. The plugin can now be installed and opened through the main QGIS menu>Manage and install Plugins.

3.HOW TO CREATE THE TOOLBAR AND THE TOOLS (buttons) AND ADD THE TOOLS ON THE TOOLBAR

Open with an editor the my_toolbar.py file and in the section of the initGui(self) write:

def initGui(self):

    self.toolBar = self.iface.addToolBar("MY TOOLBAR tools")
    self.toolBar.setObjectName("MY TOOLBAR tools")

    self.act1 = QAction(QIcon(":/plugins/Myplugintoolbar/icon.png"), QCoreApplication.translate("IMPRESStoolbar", "Tool1"), self.iface.mainWindow())
    self.act2 = QAction(QIcon(":/plugins/Myplugintoolbar/icon.png"), QCoreApplication.translate("IMPRESStoolbar", "Tool2"), self.iface.mainWindow())
    self.act3 = QAction(QIcon(":/plugins/Myplugintoolbar/icon.png"), QCoreApplication.translate("IMPRESStoolbar", "Tool3"), self.iface.mainWindow())

This way three buttons/tools have been created.

In order for the buttons to appear on the toolbar, continue writing the following:

    self.toolBar.addAction(self.act1)
    self.toolBar.addAction(self.act2)
    self.toolBar.addAction(self.act3)

In order for the buttons when clicked to open a gui continue writing the following:

    QObject.connect(self.act1, SIGNAL("triggered()"), self.runtool1)
    QObject.connect(self.act2, SIGNAL("triggered()"), self.runtool2)
    QObject.connect(self.act3, SIGNAL("triggered()"), self.runtool3)

runtool1, runtool2 and runtool3 methods are defined later as following in order to open a different gui for each button

def runtool1(self):
     self.dlgtool1.show()

def runtool2(self):
     self.dlgtool2.show()

def runtool3(self):
     self.dlgtool3.show()

That way when tool1 button is clicked the gui dlgtool1 will open, when tool2 button is clicked the dlgtool2 will open and when tool3 button is clicked the dlgtool3 gui will open.

dlgtool1, dlgtool2 and dlgtool3 should be variables pointing at the ui files representing the dialogs.

So the dialogs have to be:

  • created,

  • imported into the main py file (my_toolbar.py) and

  • assigned to variables (dlgtool1, dlgtool2 and dlgtool3 ) in order to get an instance of them.

In order to create the dialogs:

  • Copy the files my_toolbar_dialog.py and my_toolbar_dialog_base.ui and paste them inside another folder so you can rename them. Do this as many times as needed, for this example three times. Then copy these new files and paste them back to the Myplugintoolbar folder enter image description here

Open Form_dlgtool1_dialog.py with an editor in order to apply the following modifications:

From:

import os
from PyQt4 import QtGui, uic

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'my_toolbar_dialog_base.ui'))

class MyplugintoolbarDialog(QtGui.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        super(MyplugintoolbarDialog, self).__init__(parent)
        self.setupUi(self)

Change to:

import os
from PyQt4 import QtGui, uic

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'Form_dlgtool1.ui'))

class Formdlgtool1Dialog(QtGui.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        super(Formdlgtool1Dialog, self).__init__(parent)
        self.setupUi(self)

Follow the same procedure for the other two files (Form_dlgtool2_dialog.py and Form_dlgtool3_dialog.py)

Then, in order to import the dialogs into the main file open my_toolbar.py file with the editor and import the following

from Form_dlgtool1_dialog import Formdlgtool1Dialog

from Form_dlgtool2_dialog import Formdlgtool2Dialog

from Form_dlgtool3_dialog import Formdlgtool3Dialog

Finally, in order to get an instance of them, write the following inside the def __init__(self, iface) section:

self.dlgtool1 = Formdlgtool1Dialog()
self.dlgtool2 = Formdlgtool2Dialog()
self.dlgtool3 = Formdlgtool3Dialog()

Now, you can open the ui files in the QtDesigner and customize them. Then reload the plugin toolbar inside QGIS to get hte following result

enter image description here


Here's what I did to implement a second Toolbar button and its corresponding dialog:

  1. Edit the plugin.py file to add a run2() method, a self.dlg2 variable, a new action in initGui(), and this import:

    from plugin_dialog2 import pluginDialog2
    
  2. Copy and paste the UI file and rename it as form2.ui (optionally, open it in Qt-Designer and change the windowTitle property to distinguish both dialogs visually).

  3. Copy and paste the plugin_dialog.py file and rename it as plugin_dialog2.py

  4. Edit the plugin_dialog2.py file adjusting the class name to pluginDialog2, the first parameter of super to abcDialog2, and the name of the UI file:

    import os
    from PyQt4 import QtGui, uic
    
    FORM_CLASS, _ = uic.loadUiType(os.path.join(
        os.path.dirname(__file__), 'form2.ui'))
    
    class abcDialog2(QtGui.QDialog, FORM_CLASS):
        def __init__(self, parent=None):
            """Constructor."""
            super(abcDialog2, self).__init__(parent)
            self.setupUi(self)
    

You can download a demo plugin with two dialogs from here.