5
def newPolygonVector(self):
    vlt = QgsVectorLayer("Polygon?crs=EPSG:32647", "", "memory")
    vlt.dataProvider().addAttributes([QgsField("id", QVariant.Int)])
    vlt.updateFields()
    self.MakeFile()
    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = "ESRI Shapefile"
    QgsVectorFileWriter.writeAsVectorFormatV2(vlt, self.mypath + f'/FieldBorderPolygon{self.index}.shp',
                                              project.transformContext(), options)
    self.vlb = self.iface.addVectorLayer(self.mypath + f'/FieldBorderPolygon{self.index}.shp', "", "ogr")
    Symbol = QgsFillSymbol.createSimple(
        {'color_border': '#3232fa', 'width_border': '1', 'style': 'no'})
    self.vlb.renderer().setSymbol(Symbol)
    self.vlb.startEditing()
    self.vlb.triggerRepaint()

def newLineVector(self):
    vlt = QgsVectorLayer("LineString?crs=EPSG:32647", "", "memory")
    vlt.dataProvider().addAttributes([QgsField("id"
                                               , QVariant.Int)])
    vlt.updateFields()
    self.MakeFile()
    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = "ESRI Shapefile"
    QgsVectorFileWriter.writeAsVectorFormatV2(vlt, self.mypath + f'/RajahLine{self.index}.shp',
                                              project.transformContext(), options)
    self.vlr = self.iface.addVectorLayer(self.mypath + f'/RajahLine{self.index}.shp', "", "ogr")
    self.vlr.renderer().symbol().setWidth(0.6)
    self.vlr.renderer().symbol().setColor(QColor.fromRgb(255, 0, 0))



def run(self):
    """Run method that performs all the real work"""

    # Create the dialog with elements (after translation) and keep reference
    # Only create GUI ONCE in callback, so that it will only load when the plugin is started
    if self.first_start == True:
        self.first_start = False

    self.newLineVector()
    self.newPolygonVector()

    
    #Grouping
    root = project.layerTreeRoot()
    group = root.insertGroup(0, f"Prelining {self.index}")
    group.addLayer(self.vlb)
    group.addLayer(self.vlr)
    root.removeLayer(self.vlb)
    root.removeLayer(self.vlr)
  1. These are some of my code snippet for one of the processes in a plugin and the plugin is iterable.

  2. Whenever it runs the first time, it gets the result that I want, as it creates a 2 new vector outside of a group in TOC

  3. But when it comes to the second time I run the plugin, it will create the first 2 vector inside the 1st group and then will add it into 2nd group having duplicated layer in Group1 and Group2

  4. Results are shown below

1.1) This is the first time running the plugin and everything lays greatly inside the group:
enter image description here

1.2) When I click on the iterable plugin again, it will create the vector inside the previous group instead of outside the group: enter image description here

1.3) Making me having 2 duplicated layers: enter image description here

4
  • 1
    For adding your layers to the root, instead of to a group in the Layers panel, you need to write just that in your code. root = QgsProject.instance().layerTreeRoot() and then root.insertLayer(0, my_layer). On the other hand, you can read this answer to know about the recommended way of adding layers to groups. Dec 28 '20 at 17:41
  • @GermánCarrillo Hmm, it seems my other function such as QgsProject.Instance().mapLayer(my_layer.id()) can't be detected using this method. Seems like there's no layer.id() occurs Dec 29 '20 at 1:51
  • Does the 3rd image show what you want or is it the result that you don't want but the script returns? Dec 31 '20 at 19:57
  • I have read your question many times but could not understand what exactly you needed. Dec 31 '20 at 21:40
5
+100

I'm not sure if I understand your problem correctly, but I have a solution like this:

enter image description here

These are the lines I have changed or added:

def run(self):

    # other lines

    #Grouping
    root = self.project.layerTreeRoot()
    group = root.insertGroup(0, f"Prelining {self.index}")
    group.addLayer(self.vlb)
    group.addLayer(self.vlr)

    # root.removeLayer(self.vlb) <- no need these two lines
    # root.removeLayer(self.vlr) <-

def newLineVector(self):

    # other lines
    # ...

    # instead of self.iface.addVectorLayer
    self.vlr = QgsVectorLayer(
        self.mypath + f'/RajahLine{self.index}.shp',
        f"RajahLine{self.index}",  ## layer name
        "ogr")

    # renderer part
    # ...

def newPolygonVector(self):

    # other lines
    # ...

    # instead of self.iface.addVectorLayer
    self.vlb = QgsVectorLayer(
        self.mypath + f'/FieldBorderPolygon{self.index}.shp',
        f"FieldBorderPolygon{self.index}",  ## layer name
        "ogr")

    # symbol and renderer part
    # ...

QGIS ordinarily adds a new layer to the line before the active layer. In this case, it always adds to the top (pay attention to the 4th and 5th groups).

1
  • A minimal plugin using the structure above: Link Dec 31 '20 at 23:07

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.