1

I want to create multiple plugins (for example 'Plugin_1', 'Plugin_2', etc.) which are independent of each other, but which are organized in one custom menu. For example 'MyMenu'. I am also aware of these posts:
Python GUI for QGIS plugin ; how to add menu in QGIS 3.0
How to create sub-menus in QGIS 3 plugin
QGIS 2.14 Python sub-menus
Adding new menu item to QGIS Desktop app?
Grouping Custom Plugins using Python QGIS

Anyway I am stuck. With the initGUI and especially with the unload method.

I want to implement the following behaviour:
If one of the plugins is intalled/activated (for example Plugin_1) the custom menu 'MyMenu' should appear in the Menu bar with Plugin_1 as submenu.
If a further plugin is intstalled/activated (for example Plugin_2) the custom menu 'MyMenu' should now contain two submenus: Plugin_1 and Plugin_2.
If one of the plugins is uninstalled/deactivated (for example Plugin_1) the menu 'MyMenu' should now consist of one submenu which is Plugin_2.
If the last plugin is uninstalled/deactivated (in this case Plugin_2) the menu 'MyMenu' should disappear from the menu.

The code i got so far:

First of all there is one line of code in the constructor method (__init__):

self.menu = self.tr(u'&PLUGINNAME')

What does this line of code do? What do I need it for?

In the initGui method:

icon_path = ':/plugins/plugin_1/icon.png'

# check if the menu already exists
self.menu = self.iface.mainWindow().findChild( QMenu, '&MyTools')
# if not create it
if not self.menu:
    self.menu = QMenu( self.iface.mainWindow())
    self.menu.setObjectName('&MyTools')
    self.menu.setTitle('&MyTools')

# create the action
self.action = QAction(QIcon(icon_path), 'Plugin_1', self.iface.mainWindow())
self.action.setObjectName('Plugin_1')
self.action.setWhatsThis('Plugin_1')
self.action.setStatusTip('Plugin_1')
self.action.triggered.connect(self.run)
        
self.menu.addAction(self.action)

menuBar = self.iface.mainWindow().menuBar()
menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(), self.menu)

I would keep this code above in every plugin. Just replace Plugin_1 with the name of the plugin.

In the unload method:

for action in self.actions:
    self.iface.removePluginMenu(
        self.tr(u'&PLUGINNAME'), # here is still the name from the code in the constructor method
        action)
    self.iface.removeToolBarIcon(action)
menu_actions = []
for action in self.menu:
    menu_actions.append(action)
    if len(menu_actions <= 1:
        self.menu.deleteLater()

But I get the error that QMenu object is not iterable. So how do I check if my Plugin is the last one in the menu?

3

Your Answer

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

Browse other questions tagged or ask your own question.