I have a set of layers contained in several groups ("First group", "Second group" and "Third group"). I created a function where when a layer from any of these groups has its visibility toggled, it is joined by a 'parent' layer which shares the same name as the group the layer is in:
So in the example shown, if I click on Layer_1
, it will be joined to the First Group
layer. If I click on Layer_8
, it will be joined to the Third group
layer etc.
The problem is that when I click on a layer from the "First, Second or Third group", it is joined several times instead of just the once.
For example, if I click Layer_3
once and then check the Joins properties:
Here is the code:
from PyQt4.QtCore import *
root = QgsProject.instance().layerTreeRoot()
main_group = root.findGroup('Main group')
layerField = 'ID'
def update_joins():
for group in main_group.children():
layer = QgsMapLayerRegistry.instance().mapLayersByName( group.name() )[-1]
for child in group.children():
node = root.findLayer(child.layer().id())
if node.isVisible() == Qt.Checked:
childField = 'ID'
joinObject = QgsVectorJoinInfo()
joinObject.joinLayerId = child.layer().id()
joinObject.joinFieldName = childField
joinObject.targetFieldName = layerField
joinObject.memoryCache = True
layer.addJoin(joinObject)
else:
layer.removeJoin(child.layer().id())
root.visibilityChanged.connect(update_joins)
I'm not exactly sure why it is being joined several times, is there a way to make sure it is only joined once?
I checked QgsVectorJoinInfo and the QgsVectorLayer::vectorJoins to see if it is possible to do a check (i.e. if this layer has been joined then pass
) but couldn't find much information.
layer.removeJoin(child.layer().id())
directly after theif node.isVisible() == Qt.Checked:
statement, the final product is that the layer is only joined once. However, the unnecessary looping is not really efficient so will try and see about creating your logic :)