8

I want to create a toolbar with 2 buttons, each button opening a different form.

The steps I followed are:

  • Created a plugin using Plugin builder

  • Created a toolbar with 2 buttons by doing the necessary modifications in the implementation file.

Until here, everything works fine, so when first button is clicked, the corresponding form opens correctly. This form is the one created by the Plugin builder.

Then I want to have a second form which will open when the second button is clicked. So:

  • Created a new form in Qt designer (form2.ui),

  • Translated the ui file to py file (make) and imported the class from the translated py file into the implementation file, got an instance of the class (self.dlg2 = Ui_form2())

and in the run() method of the implementation file I wrote:

def run2(self):
    self.dlg2.show()
    result = self.dlg2.exec_()

But then I get an error message that this new form has no .show() method. Should it inherit something in order to implement the .show() method? But how can I modify the code of the second form in order to inherit something since all changes in the translated py file from the ui file cannot be saved?

4

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.

  • Thank you very much!!! This is working fine and at the same time it gave a better understanding of the plugin building.. So, I would assume that the above procedure can be applied more times, if for example I want to have 3 or 4 buttons, each one opening a different form. But my 3rd button doesn' t appear on the toolbar. Any idea why this is happening? – Eleftheria May 25 '16 at 10:48
  • 1
    Right, it should work as many times as you need, as long as you keep an order naming variables, classes, and the like. For instance, to add your 3rd button you would need to add a new action in initGui(), this way: self.add_action( icon_path, text=self.tr(u'plugin3'), callback=self.run3, parent=self.iface.mainWindow()) – Germán Carrillo May 25 '16 at 11:52
  • Well, it works ok in the end after I restarted my computer... – Eleftheria May 26 '16 at 10:41
8

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

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.