I am updating a plugin for QGIS 1.8 to QGIS 2.x. I have the code below.
The setAttributeMap does not exist anymore. I have replaced it with fet.setAttributes and it seems to work.
When using fet.setAttributes({0:QVariant(fid}), I get the error:
PyQt4.QtCore.QVariant represents a mapped type and cannot be instantiated.
I have tried to just remove the QVariant() and used fet.setAttributes({0:fid}), but then I get the error:
TypeError: QgsFeature.setAttributes(list-of-attributes): argument 1 has unexpected type 'dict'
The code worked well with 1.8, so what can I do to replace QVariant or setAttributeMap? I think it could be something with changing setAttributeMap to setAttributes
vl = QgsVectorLayer("MultiLineString", layerName, "memory")
pr = vl.dataProvider()
vl.startEditing()
pr.addAttributes([QgsField("id", QVariant.Int)])
fet = QgsFeature()
addRange = northRange * math.tan(abs(math.radians(bearing)))
noPoints = ((eastRange + addRange) / projEast) + 1
for i in range(0,int(math.ceil(noPoints)), 1):
fet.setGeometry( QgsGeometry.fromMultiPolyline( [[ QgsPoint(minE + offset + (projEast * i) ,minN), QgsPoint(minE + offset + (projEast * i) - addRange,maxN) ]] ))
fet.setAttributeMap({0:QVariant(fid)})
pr.addFeatures( [ fet ] )
fid = fid + 1
vl.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(vl)
I have change my code to:
vl = QgsVectorLayer("MultiLineString", layerName, "memory")
pr = vl.dataProvider()
vl.startEditing()
pr.addAttributes([QgsField("id", QVariant.Int)])
fet = QgsFeature()
fields = vl.pendingFields()
fet.setFields( fields, True )
addRange = northRange * math.tan(abs(math.radians(bearing)))
noPoints = ((eastRange + addRange) / projEast) + 1
for i in range(0,int(math.ceil(noPoints)), 1):
fet.setGeometry( QgsGeometry.fromMultiPolyline( [[ QgsPoint(minE + offset + (projEast * i) ,minN), QgsPoint(minE + offset + (projEast * i) - addRange,maxN) ]] ))
fet['id'] = fid
pr.addFeatures( [ fet ] )
fid = fid + 1
vl.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(vl)
but I still need to make an attribute named 'id' I guess before it works. If I use the setAttributes function it includes a QVariant which I am not allowed to do!
Or is it me who does not understand.
This is the final code, and it is working:
vl = QgsVectorLayer("MultiLineString", layerName, "memory")
vl.startEditing()
vl.addAttribute(QgsField("id", QVariant.Int))
fet = QgsFeature()
fields = vl.pendingFields()
fet.setFields( fields, True )
addRange = northRange * math.tan(abs(math.radians(bearing)))
noPoints = ((eastRange + addRange) / projEast) + 1
for i in range(0,int(math.ceil(noPoints)), 1):
fet.setGeometry( QgsGeometry.fromMultiPolyline( [[ QgsPoint(minE + offset + (projEast * i) ,minN), QgsPoint(minE + offset + (projEast * i) - addRange,maxN) ]] ))
fet['id'] = fid
vl.addFeatures( [ fet ] )
fid = fid + 1
vl.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(vl)
Answer
You can still use QVariant
but don't use it as a type.
E.g. the following is still fine:
from PyQt4.QtCore import QVariant
vl.startEditing()
vl.addAttribute(QgsField("id", QVariant.Int))
However, it is no longer required (and no longer allowed) to use QVariant
as a datatype. This means, instead of QVariant(fid)
you should just use fid
. You already have posted a link to the relevant section in the API changes.
The API also changed in terms of vector layer handling, which can be confused with the changes concerning QVariant
but it's a different pair of shoes.
The relevant code for this is:
fet = QgsFeature()
fields = vl.pendingFields()
fet.setFields( fields, True )
fet['id'] = 42
And a minor note:
- If you directly work on the dataprovider (
pr.addFeatures()
,pr.addAttributes()
) there is no need to toggle layer editing (vl.startEditing()
,vl.commitChanges()
). If you want an undo stack, use theQgsVectorLayer
methods instead of theQgsVectorDataProvider
methods (i.e. by usingvl.[method]
instead ofpr.[method]
. If you work directly on the dataprovider, another caveat is, that events (updated features...) may not be propagated properly and lead to inconsistencies in the representation (attribute table...). TL;DR: Usevl.addFeature()
instead ofpr.addFeatures()
No comments:
Post a Comment