I have created a drop down menu in QGIS. The code is mainly from the "Layers menu from project" plugin. I have cleaned it so it only have the drop down.
My problem is that I will like to add an extra item to the drop down (a "Info" item, or "about the plugin"), but I can't figure out where to add it to the code.
I added the following just above return yaLayer, but it resulted in a 'Extra item' for each other item in the drop down.
menu.addSeparator()
menu.addMenuitem('Extra item')
Does anyone know where to add it or give a hint?
Entire code:
from __future__ import unicode_literals
# Import the PyQt and QGIS libraries
import os
import sys
from qgis.core import *
from PyQt4 import QtWebKit
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtXml
from menu_conf_dlg import menu_conf_dlg
# Initialize Qt resources from file resources.py
import resources
def getFirstChildByTagNameValue(elt, tagName, key, value):
nodes = elt.elementsByTagName(tagName)
for node in (nodes.at(i) for i in range(nodes.size())):
idNode = node.namedItem(key)
if idNode and value == idNode.firstChild().toText().data():
# layer founds
return node
return None
class menu_from_project:
def __init__(self, iface):
self.path = QFileInfo(os.path.realpath(__file__)).path()
self.iface = iface
self.toolBar = None
# new multi projects var
self.projects = []
self.menubarActions = []
self.canvas = self.iface.mapCanvas()
self.optionTooltip = (False)
self.optionCreateGroup = (False)
self.optionLoadAll = (False)
self.read()
# default lang
locale = QSettings().value("locale/userLocale")
self.myLocale = locale[0:2]
def store(self):
s = QSettings()
s.remove("menu_from_project/projectFilePath")
index = 0
s.setValue("menu_from_project/optionTooltip", (self.optionTooltip))
s.setValue("menu_from_project/optionCreateGroup", (self.optionCreateGroup))
s.setValue("menu_from_project/optionLoadAll", (self.optionLoadAll))
s.beginWriteArray("menu_from_project/projects")
for project in self.projects:
s.setArrayIndex(index)
s.setValue("file", project["file"])
s.setValue("name", project["name"])
index = index + 1
s.endArray()
def read(self):
s = QSettings()
try:
# old single project conf
filePath = s.value("menu_from_project/projectFilePath", "")
if filePath:
title = str(filePath).split('/')[-1]
title = str(title).split('.')[0]
self.projects.append({"file":filePath, "name":title})
self.store()
else:
# patch : lecture ancienne conf
size = s.beginReadArray("projects")
for i in range(size):
s.setArrayIndex(i)
file = ((s.value("file").toString()))
name = ((s.value("name").toString()))
if file:
self.projects.append({"file":file, "name":(name)})
s.endArray()
size = s.beginReadArray("menu_from_project/projects")
for i in range(size):
s.setArrayIndex(i)
file = s.value("file", "")
name = s.value("name", "")
if file != "":
self.projects.append({"file":file, "name":name})
s.endArray()
self.optionTooltip = s.value("menu_from_project/optionTooltip", (True), type=bool)
# create group option only since 1.9
self.optionCreateGroup = s.value("menu_from_project/optionCreateGroup", (False), type=bool)
self.optionLoadAll = s.value("menu_from_project/optionLoadAll", (False), type=bool)
except:
pass
def isAbsolute(self, doc):
absolute = False
try:
props = doc.elementsByTagName("properties")
if props.count()==1:
node = props.at(0)
pathNode = node.namedItem("Paths")
absoluteNode = pathNode.namedItem("Absolute")
absolute = ("true" == absoluteNode.firstChild().toText().data())
except:
pass
return absolute
def _actionHovered(self, action):
tip = action.toolTip()
if (tip != "-"):
QToolTip.showText(QCursor.pos(), tip)
else:
QToolTip.hideText()
def getMaplayerDomFromQgs(self, fileName, layerId):
xml = file(unicode(fileName)).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
maplayers = doc.elementsByTagName("maplayer")
for ml in (maplayers.item(i) for i in range(maplayers.size())):
idelt = ml.namedItem("id")
id = ""
if idelt and layerId == idelt.firstChild().toText().data():
return ml
return None
def addMenuItem(self, filename, node, menu, domdoc):
yaLayer = False
initialFilename = filename
if node == None:
return yaLayer
element = node.toElement()
# if legendlayer tag
if node.nodeName() == "legendlayer":
try:
legendlayerfileElt = element.firstChild().firstChildElement("legendlayerfile")
layerId = legendlayerfileElt.attribute("layerid")
action = QAction(element.attribute("name"), self.iface.mainWindow())
if (self.optionTooltip == (True)):
try:
maplayers = domdoc.elementsByTagName("maplayer")
for ml in (maplayers.item(i) for i in range(maplayers.size())):
idelt = ml.namedItem("id")
id = ""
if (idelt != None):
id = idelt.firstChild().toText().data()
attrEmbedded = ml.toElement().attribute("embedded", "0")
if (attrEmbedded == "1"):
id = ml.toElement().attribute("id", "")
if (id == layerId):
# embedded layers ?
embeddedFilename = ""
if (attrEmbedded == "1"):
try:
embeddedFilename = ml.toElement().attribute("project", "")
# read embedded project
if not self.absolute and (embeddedFilename.find(".")==0):
embeddedFilename = self.projectpath + "/" + embeddedFilename
ml = self.getMaplayerDomFromQgs(embeddedFilename, id)
filename = embeddedFilename
except:
pass
if ml != None:
try:
title = ml.namedItem("title").firstChild().toText().data()
abstract = ml.namedItem("abstract").firstChild().toText().data()
action.setStatusTip(title)
if (abstract != "") and (title == ""):
action.setToolTip("<p>%s</p>" % (abstract))
else:
if (abstract != "" or title != ""):
action.setToolTip("<b>%s</b><br/>%s" % (title, abstract))
else:
action.setToolTip("-")
except:
pass
else:
QgsMessageLog.logMessage(id+" not found in project "+embeddedFilename, 'Extensions')
break
except:
pass
menu.addAction(action)
yaLayer = True
helper = lambda _filename,_who,_menu: (lambda: self.do_aeag_menu(_filename, _who, _menu))
action.triggered.connect(helper(filename, layerId, menu))
except:
pass
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
# / if element.tagName() == "legendlayer":
# if legendgroup tag
if node.nodeName() == "legendgroup":
name = element.attribute("name")
if name == "-":
menu.addSeparator()
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
elif name.startswith("-"):
action = QAction(name[1:], self.iface.mainWindow())
font = QFont()
font.setBold(True)
action.setFont(font)
menu.addAction(action)
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
else:
#messageLog("Group %s" % (element.attribute("name")))
# construire sous-menu
sousmenu = menu.addMenu('&'+element.attribute("name"))
sousmenu.menuAction().setToolTip("-")
childNode = node.firstChild()
# ! recursion
r = self.addMenuItem(initialFilename, childNode, sousmenu, domdoc)
if r and self.optionLoadAll and (len(sousmenu.actions()) > 1):
action = QAction(QApplication.translate("menu_from_project", "&Load all", None, QApplication.UnicodeUTF8), self.iface.mainWindow())
font = QFont()
font.setBold(True)
action.setFont(font)
sousmenu.addAction(action)
helper = lambda _filename,_who,_menu: (lambda: self.do_aeag_menu(_filename, _who, _menu))
action.triggered.connect(helper(None, None, sousmenu))
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
# / if element.tagName() == "legendgroup":
#below works but add a lot
#menu.addSeparator()
#menu.addMenuitem('actiontest')
return yaLayer
def addMenu(self, name, filename, domdoc):
# main project menu
menuBar = self.iface.editMenu().parentWidget()
projectMenu = QMenu('&'+name, menuBar)
if (self.optionTooltip == (True)):
projectMenu.hovered.connect(self._actionHovered)
projectAction = menuBar.addMenu(projectMenu)
self.menubarActions.append(projectAction);
self.absolute = self.isAbsolute(domdoc)
self.projectpath = QFileInfo(os.path.realpath(filename)).path()
# build menu on legend schema
legends = domdoc.elementsByTagName("legend")
if (legends.length() > 0):
node = legends.item(0)
if node:
node = node.firstChild()
self.addMenuItem(filename, node, projectMenu, domdoc)
# Seperate settings from actual content
def initMenus(self):
menuBar = self.iface.editMenu().parentWidget()
for action in self.menubarActions:
menuBar.removeAction(action)
del(action)
self.menubarActions = []
QgsApplication.setOverrideCursor(Qt.WaitCursor)
for project in self.projects:
try:
xml = file(unicode(project["file"])).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
self.addMenu(project["name"], project["file"], doc)
except:
QgsMessageLog.logMessage('Menu from layer : invalid ' + str(project["file"]), 'Extensions')
pass
QgsApplication.restoreOverrideCursor()
def initGui(self):
# build menu
self.initMenus()
# run method that performs all the real work
def do_aeag_menu(self, filename, who, menu=None):
self.canvas.freeze(True)
self.canvas.setRenderFlag(False)
idxGroup = None
theLayer = None
groupName = None
QgsApplication.setOverrideCursor(Qt.WaitCursor)
try:
if type(menu.parentWidget()) == QMenu and self.optionCreateGroup:
groupName = menu.title().replace("&", "")
idxGroup = self.iface.legendInterface().groups().index(groupName) if groupName in self.iface.legendInterface().groups() else -1
if idxGroup < 0:
idxGroup = self.iface.legendInterface().addGroup(groupName, True)
# load all layers
if filename == None and who == None and self.optionLoadAll:
i = 0
for action in reversed(menu.actions()):
if action.text() != QApplication.translate("menu_from_project", "&Load all", None, QApplication.UnicodeUTF8):
action.trigger()
else:
# read QGis project
xml = file(unicode(filename)).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
# is project in relative path ?
absolute = self.isAbsolute(doc)
node = getFirstChildByTagNameValue(doc.documentElement(), "maplayer", "id", who)
if node:
idNode = node.namedItem("id")
# give it a new id (for multiple import)
try:
import uuid
import re
newLayerId = "L%s" % re.sub("[{}-]", "", QUuid.createUuid().toString())
idNode.firstChild().toText().setData(newLayerId)
except:
pass
# if relative path, adapt datasource
if not absolute:
try:
datasourceNode = node.namedItem("datasource")
datasource = datasourceNode.firstChild().toText().data()
providerNode = node.namedItem("provider")
provider = providerNode.firstChild().toText().data()
if provider == "ogr" and (datasource.find(".")==0):
projectpath = QFileInfo(os.path.realpath(filename)).path()
newlayerpath = projectpath + "/" + datasource
datasourceNode.firstChild().toText().setData(newlayerpath)
except:
pass
# read modified layer node
QgsProject.instance().read(node)
if self.optionCreateGroup:
theLayer = QgsMapLayerRegistry.instance().mapLayer(newLayerId)
if idxGroup >= 0 and theLayer != None:
self.iface.mainWindow().statusBar().showMessage("Move to group "+str(idxGroup))
self.iface.legendInterface().refreshLayerSymbology(theLayer)
self.iface.legendInterface().moveLayer(theLayer, idxGroup)
self.iface.legendInterface().refreshLayerSymbology(theLayer)
except:
QgsMessageLog.logMessage('Menu from layer : invalid ' + filename, 'Extensions')
pass
self.canvas.freeze(False)
self.canvas.setRenderFlag(True)
self.canvas.refresh()
QgsApplication.restoreOverrideCursor()
def doLink( self, url ):
if url.host() == "" :
self.hdialog.ui.helpContent.page().currentFrame().load(url)
else:
QDesktopServices.openUrl( url )
-
1You should create an action (QAction), and you can add this action to a menu. Look in the source code of any Python plug-in with menu.Zoltan– Zoltan2016年12月11日 13:44:45 +00:00Commented Dec 11, 2016 at 13:44
1 Answer 1
You can copy the style used in the "Layers menu from project" for the other two items (Projects configuration
and Help
) and rename it slightly to fit your requirements.
initGui()
In the initGui()
function (I am using the source code for the plugin), it reads the following:
def initGui(self):
self.act_aeag_menu_config = QAction(QApplication.translate("menu_from_project", "Projects configuration", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
# Add actions to the toolbar
self.act_aeag_menu_config.triggered.connect(self.do_aeag_menu_config)
self.act_aeag_menu_help = QAction(QApplication.translate("menu_from_project", "Help", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
self.act_aeag_menu_help.triggered.connect(self.do_help)
# build menu
self.initMenus()
As Zoltan mentioned, we can create a QAction and add it as a menu. In the above code, it shows how the other two items are being added. So we can just copy it and change the name slightly:
def initGui(self):
self.act_aeag_menu_config = QAction(QApplication.translate("menu_from_project", "Projects configuration", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
# Add actions to the toolbar
self.act_aeag_menu_config.triggered.connect(self.do_aeag_menu_config)
self.act_aeag_menu_help = QAction(QApplication.translate("menu_from_project", "Help", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
self.act_aeag_menu_help.triggered.connect(self.do_help)
# Here we added a QAction for 'Extra item'
self.act_aeag_menu_extraItem = QAction(QApplication.translate("menu_from_project", "Extra item", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_extraItem)
self.act_aeag_menu_extraItem.triggered.connect(self.do_extraItem)
# build menu
self.initMenus()
do_extraItem()
We need to define a function for what happens when the "Extra item" menu has been clicked. We already connected the QAction to a function called do_extraItem()
but now we have to define this new function. Here's a simple example:
def do_extraItem(self):
print "Hopefully this works!"
unload()
Finally, to avoid creating duplicate items in the menu, we need to remove and disconnect the QAction from the menu. Here is the original source code:
def unload(self):
menuBar = self.iface.editMenu().parentWidget()
for action in self.menubarActions:
menuBar.removeAction(action)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
self.act_aeag_menu_config.triggered.disconnect(self.do_aeag_menu_config)
self.act_aeag_menu_help.triggered.disconnect(self.do_help)
self.store()
Again we can repeat the similar lines of code used for our new menu item:
def unload(self):
menuBar = self.iface.editMenu().parentWidget()
for action in self.menubarActions:
menuBar.removeAction(action)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
# New line added below
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_extraItem)
self.act_aeag_menu_config.triggered.disconnect(self.do_aeag_menu_config)
self.act_aeag_menu_help.triggered.disconnect(self.do_help)
# New line added below
self.act_aeag_menu_extraItem.triggered.disconnect(self.do_extraItem)
self.store()
And hopefully, that should help get you started:
Edit:
This is the complete script for the menu_from_project.py
file that I edited to show the extra item. Copy/paste the whole code into the said file, reload the plugin (or QGIS) and you should see the extra menu option. Make sure to back up your original file!
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
# Import the PyQt and QGIS libraries
import os
import sys
from qgis.core import *
from PyQt4 import QtWebKit
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtXml
from ui_browser import Ui_browser
from menu_conf_dlg import menu_conf_dlg
# Initialize Qt resources from file resources.py
import resources
def getFirstChildByTagNameValue(elt, tagName, key, value):
nodes = elt.elementsByTagName(tagName)
for node in (nodes.at(i) for i in range(nodes.size())):
idNode = node.namedItem(key)
if idNode and value == idNode.firstChild().toText().data():
# layer founds
return node
return None
class menu_from_project:
def __init__(self, iface):
self.path = QFileInfo(os.path.realpath(__file__)).path()
self.iface = iface
self.toolBar = None
# new multi projects var
self.projects = []
self.menubarActions = []
self.canvas = self.iface.mapCanvas()
self.optionTooltip = (False)
self.optionCreateGroup = (False)
self.optionLoadAll = (False)
self.read()
# default lang
locale = QSettings().value("locale/userLocale")
self.myLocale = locale[0:2]
# dictionnary
localePath = self.path+"/i18n/menu_from_project_" + self.myLocale + ".qm"
# translator
if QFileInfo(localePath).exists():
self.translator = QTranslator()
self.translator.load(localePath)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
def store(self):
s = QSettings()
s.remove("menu_from_project/projectFilePath")
index = 0
s.setValue("menu_from_project/optionTooltip", (self.optionTooltip))
s.setValue("menu_from_project/optionCreateGroup", (self.optionCreateGroup))
s.setValue("menu_from_project/optionLoadAll", (self.optionLoadAll))
s.beginWriteArray("menu_from_project/projects")
for project in self.projects:
s.setArrayIndex(index)
s.setValue("file", project["file"])
s.setValue("name", project["name"])
index = index + 1
s.endArray()
def read(self):
s = QSettings()
try:
# old single project conf
filePath = s.value("menu_from_project/projectFilePath", "")
if filePath:
title = str(filePath).split('/')[-1]
title = str(title).split('.')[0]
self.projects.append({"file":filePath, "name":title})
self.store()
else:
# patch : lecture ancienne conf
size = s.beginReadArray("projects")
for i in range(size):
s.setArrayIndex(i)
file = ((s.value("file").toString()))
name = ((s.value("name").toString()))
if file:
self.projects.append({"file":file, "name":(name)})
s.endArray()
size = s.beginReadArray("menu_from_project/projects")
for i in range(size):
s.setArrayIndex(i)
file = s.value("file", "")
name = s.value("name", "")
if file != "":
self.projects.append({"file":file, "name":name})
s.endArray()
self.optionTooltip = s.value("menu_from_project/optionTooltip", (True), type=bool)
# create group option only since 1.9
self.optionCreateGroup = s.value("menu_from_project/optionCreateGroup", (False), type=bool)
self.optionLoadAll = s.value("menu_from_project/optionLoadAll", (False), type=bool)
except:
pass
def isAbsolute(self, doc):
absolute = False
try:
props = doc.elementsByTagName("properties")
if props.count()==1:
node = props.at(0)
pathNode = node.namedItem("Paths")
absoluteNode = pathNode.namedItem("Absolute")
absolute = ("true" == absoluteNode.firstChild().toText().data())
except:
pass
return absolute
def _actionHovered(self, action):
tip = action.toolTip()
if (tip != "-"):
QToolTip.showText(QCursor.pos(), tip)
else:
QToolTip.hideText()
def getMaplayerDomFromQgs(self, fileName, layerId):
xml = file(unicode(fileName)).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
maplayers = doc.elementsByTagName("maplayer")
for ml in (maplayers.item(i) for i in range(maplayers.size())):
idelt = ml.namedItem("id")
id = ""
if idelt and layerId == idelt.firstChild().toText().data():
return ml
return None
def addMenuItem(self, filename, node, menu, domdoc):
yaLayer = False
initialFilename = filename
if node == None:
return yaLayer
element = node.toElement()
# if legendlayer tag
if node.nodeName() == "legendlayer":
try:
legendlayerfileElt = element.firstChild().firstChildElement("legendlayerfile")
layerId = legendlayerfileElt.attribute("layerid")
action = QAction(element.attribute("name"), self.iface.mainWindow())
if (self.optionTooltip == (True)):
try:
maplayers = domdoc.elementsByTagName("maplayer")
for ml in (maplayers.item(i) for i in range(maplayers.size())):
idelt = ml.namedItem("id")
id = ""
if (idelt != None):
id = idelt.firstChild().toText().data()
attrEmbedded = ml.toElement().attribute("embedded", "0")
if (attrEmbedded == "1"):
id = ml.toElement().attribute("id", "")
if (id == layerId):
# embedded layers ?
embeddedFilename = ""
if (attrEmbedded == "1"):
try:
embeddedFilename = ml.toElement().attribute("project", "")
# read embedded project
if not self.absolute and (embeddedFilename.find(".")==0):
embeddedFilename = self.projectpath + "/" + embeddedFilename
ml = self.getMaplayerDomFromQgs(embeddedFilename, id)
filename = embeddedFilename
except:
pass
if ml != None:
try:
title = ml.namedItem("title").firstChild().toText().data()
abstract = ml.namedItem("abstract").firstChild().toText().data()
action.setStatusTip(title)
if (abstract != "") and (title == ""):
action.setToolTip("<p>%s</p>" % (abstract))
else:
if (abstract != "" or title != ""):
action.setToolTip("<b>%s</b><br/>%s" % (title, abstract))
else:
action.setToolTip("-")
except:
pass
else:
QgsMessageLog.logMessage(id+" not found in project "+embeddedFilename, 'Extensions')
break
except:
pass
menu.addAction(action)
yaLayer = True
helper = lambda _filename,_who,_menu: (lambda: self.do_aeag_menu(_filename, _who, _menu))
action.triggered.connect(helper(filename, layerId, menu))
except:
pass
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
# / if element.tagName() == "legendlayer":
# if legendgroup tag
if node.nodeName() == "legendgroup":
name = element.attribute("name")
if name == "-":
menu.addSeparator()
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
elif name.startswith("-"):
action = QAction(name[1:], self.iface.mainWindow())
font = QFont()
font.setBold(True)
action.setFont(font)
menu.addAction(action)
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
else:
#messageLog("Group %s" % (element.attribute("name")))
# construire sous-menu
sousmenu = menu.addMenu('&'+element.attribute("name"))
sousmenu.menuAction().setToolTip("-")
childNode = node.firstChild()
# ! recursion
r = self.addMenuItem(initialFilename, childNode, sousmenu, domdoc)
if r and self.optionLoadAll and (len(sousmenu.actions()) > 1):
action = QAction(QApplication.translate("menu_from_project", "&Load all", None, QApplication.UnicodeUTF8), self.iface.mainWindow())
font = QFont()
font.setBold(True)
action.setFont(font)
sousmenu.addAction(action)
helper = lambda _filename,_who,_menu: (lambda: self.do_aeag_menu(_filename, _who, _menu))
action.triggered.connect(helper(None, None, sousmenu))
nextNode = node.nextSibling()
if (nextNode != None):
# ! recursion
self.addMenuItem(initialFilename, nextNode, menu, domdoc)
# / if element.tagName() == "legendgroup":
return yaLayer
def addMenu(self, name, filename, domdoc):
# main project menu
menuBar = self.iface.editMenu().parentWidget()
projectMenu = QMenu('&'+name, menuBar)
if (self.optionTooltip == (True)):
projectMenu.hovered.connect(self._actionHovered)
projectAction = menuBar.addMenu(projectMenu)
self.menubarActions.append(projectAction);
self.absolute = self.isAbsolute(domdoc)
self.projectpath = QFileInfo(os.path.realpath(filename)).path()
# build menu on legend schema
legends = domdoc.elementsByTagName("legend")
if (legends.length() > 0):
node = legends.item(0)
if node:
node = node.firstChild()
self.addMenuItem(filename, node, projectMenu, domdoc)
def initMenus(self):
menuBar = self.iface.editMenu().parentWidget()
for action in self.menubarActions:
menuBar.removeAction(action)
del(action)
self.menubarActions = []
QgsApplication.setOverrideCursor(Qt.WaitCursor)
for project in self.projects:
try:
xml = file(unicode(project["file"])).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
self.addMenu(project["name"], project["file"], doc)
except:
QgsMessageLog.logMessage('Menu from layer : invalid ' + str(project["file"]), 'Extensions')
pass
QgsApplication.restoreOverrideCursor()
def initGui(self):
self.act_aeag_menu_config = QAction(QApplication.translate("menu_from_project", "Projects configuration", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
# Add actions to the toolbar
self.act_aeag_menu_config.triggered.connect(self.do_aeag_menu_config)
self.act_aeag_menu_help = QAction(QApplication.translate("menu_from_project", "Help", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
self.act_aeag_menu_help.triggered.connect(self.do_help)
# Here we added a QAction for 'Extra item'
self.act_aeag_menu_extraItem = QAction(QApplication.translate("menu_from_project", "Extra item", None, QApplication.UnicodeUTF8)+"...", self.iface.mainWindow())
self.iface.addPluginToMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_extraItem)
self.act_aeag_menu_extraItem.triggered.connect(self.do_extraItem)
# build menu
self.initMenus()
def do_extraItem(self):
# Extra item function
# Print following in the python console as a test to see if it successfully connects with the menu option
print "Hopefully this works!"
def unload(self):
menuBar = self.iface.editMenu().parentWidget()
for action in self.menubarActions:
menuBar.removeAction(action)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_config)
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_help)
# New line added below
self.iface.removePluginMenu(QApplication.translate("menu_from_project", "&Layers menu from project", None, QApplication.UnicodeUTF8), self.act_aeag_menu_extraItem)
self.act_aeag_menu_config.triggered.disconnect(self.do_aeag_menu_config)
self.act_aeag_menu_help.triggered.disconnect(self.do_help)
# New line added below
self.act_aeag_menu_extraItem.triggered.disconnect(self.do_extraItem)
self.store()
def do_aeag_menu_config(self):
dlg = menu_conf_dlg(self.iface.mainWindow(), self)
dlg.setModal(True)
dlg.show()
result = dlg.exec_()
del dlg
if result != 0:
self.initMenus()
# run method that performs all the real work
def do_aeag_menu(self, filename, who, menu=None):
self.canvas.freeze(True)
self.canvas.setRenderFlag(False)
idxGroup = None
theLayer = None
groupName = None
QgsApplication.setOverrideCursor(Qt.WaitCursor)
try:
if type(menu.parentWidget()) == QMenu and self.optionCreateGroup:
groupName = menu.title().replace("&", "")
idxGroup = self.iface.legendInterface().groups().index(groupName) if groupName in self.iface.legendInterface().groups() else -1
if idxGroup < 0:
idxGroup = self.iface.legendInterface().addGroup(groupName, True)
# load all layers
if filename == None and who == None and self.optionLoadAll:
i = 0
for action in reversed(menu.actions()):
if action.text() != QApplication.translate("menu_from_project", "&Load all", None, QApplication.UnicodeUTF8):
action.trigger()
else:
# read QGis project
xml = file(unicode(filename)).read()
doc = QtXml.QDomDocument()
doc.setContent(xml)
# is project in relative path ?
absolute = self.isAbsolute(doc)
node = getFirstChildByTagNameValue(doc.documentElement(), "maplayer", "id", who)
if node:
idNode = node.namedItem("id")
# give it a new id (for multiple import)
try:
import uuid
import re
newLayerId = "L%s" % re.sub("[{}-]", "", QUuid.createUuid().toString())
idNode.firstChild().toText().setData(newLayerId)
except:
pass
# if relative path, adapt datasource
if not absolute:
try:
datasourceNode = node.namedItem("datasource")
datasource = datasourceNode.firstChild().toText().data()
providerNode = node.namedItem("provider")
provider = providerNode.firstChild().toText().data()
if provider == "ogr" and (datasource.find(".")==0):
projectpath = QFileInfo(os.path.realpath(filename)).path()
newlayerpath = projectpath + "/" + datasource
datasourceNode.firstChild().toText().setData(newlayerpath)
except:
pass
# read modified layer node
QgsProject.instance().read(node)
if self.optionCreateGroup:
theLayer = QgsMapLayerRegistry.instance().mapLayer(newLayerId)
if idxGroup >= 0 and theLayer != None:
self.iface.mainWindow().statusBar().showMessage("Move to group "+str(idxGroup))
self.iface.legendInterface().refreshLayerSymbology(theLayer)
self.iface.legendInterface().moveLayer(theLayer, idxGroup)
self.iface.legendInterface().refreshLayerSymbology(theLayer)
except:
QgsMessageLog.logMessage('Menu from layer : invalid ' + filename, 'Extensions')
pass
self.canvas.freeze(False)
self.canvas.setRenderFlag(True)
self.canvas.refresh()
QgsApplication.restoreOverrideCursor()
def do_help(self):
try:
self.hdialog = QDialog()
self.hdialog.setModal(True)
self.hdialog.ui = Ui_browser()
self.hdialog.ui.setupUi(self.hdialog)
if os.path.isfile(self.path+"/help_"+self.myLocale+".html"):
self.hdialog.ui.helpContent.setUrl(QUrl(self.path+"/help_"+self.myLocale+".html"))
else:
self.hdialog.ui.helpContent.setUrl(QUrl(self.path+"/help.html"))
self.hdialog.ui.helpContent.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateExternalLinks) # Handle link clicks by yourself
self.hdialog.ui.helpContent.linkClicked.connect(self.doLink)
self.hdialog.ui.helpContent.page().currentFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOn)
self.hdialog.show()
result = self.hdialog.exec_()
del self.hdialog
except:
QgsMessageLog.logMessage(sys.exc_info()[0], 'Extensions')
pass
def doLink( self, url ):
if url.host() == "" :
self.hdialog.ui.helpContent.page().currentFrame().load(url)
else:
QDesktopServices.openUrl( url )
-
Thank you so much for your answer. I think the anser it righ. i think it works with that plugin as you show. But i cant add it to my code, i dont now where to put the extra stuff. Du you have any inputs if you take a look at the code i have in my question? ThanksLAC– LAC2016年12月22日 10:38:45 +00:00Commented Dec 22, 2016 at 10:38
-
@student - Most welcome, I've edited the post to include the complete script I used. Back up your original file and replace the code with the one above and test it out :)Joseph– Joseph2016年12月22日 10:54:00 +00:00Commented Dec 22, 2016 at 10:54
-
1Thank again. I just marked it at correct. My next problem is to add the extra item the correct place. But i might come back to that.LAC– LAC2017年01月28日 12:11:39 +00:00Commented Jan 28, 2017 at 12:11
-
@student - Most welcome! Glad it was helpful =)Joseph– Joseph2017年01月30日 10:08:11 +00:00Commented Jan 30, 2017 at 10:08