Message posté par : F.Duval
----------------------------------------
Bonjour à tous,
Et merci à ceux qui prendront la peine de lire. Je suis novice dans le développement
Python pour QGIS.
J'essaye de faire des auto-exercices 'step by step' pour acquérir les
notions/traitement de bases, en suivant principalement le cookbook version 3.4.
A l'avenir j'aimerais (évidemment) être capable de remplir, pour chaque objet, un
champ avec une valeur issu d'un calcul préalable, d'une géométrie d'une autre
couche, etc...
Pour le moment je bloque pour tout simplement modifier un champ que je viens de créer (ici
'Alors') pour remplacer les 'NULL' par une valeur constante (ici 'Bien
joué').
Voici mon code
[Je sais qu'il y a des choses inutiles, surtout au début de celui ci, mais cela me
permet de garder une trace de chaque petite étape, pour plus tard)
-----------------
Code :
from qgis.core import *
from qgis.utils import *
from qgis.gui import *
iface=qgis.utils.iface
pjt=QgsProject.instance()
canvas=iface.mapCanvas()
for layer in canvas.layers():
print (layer.name())
#Renvoie :
#"Troncon CTRL"
#"Listing GEOSAT"
#"Listing CTRL"
Tctrl = canvas.layers()[0]
Lgeosat = canvas.layers()[1]
Lctrl = canvas.layers()[2]
#les numéros sont, a priori, dans l'ordre du canvas
print(Lctrl.name())
#Renvoie : "Listing CTRL"
iface.setActiveLayer(Lgeosat)
#Listing GEOSAT devient la couche sélectionnée
XLctrl=Lctrl.dataProvider().fields()[0]
caps = Lctrl.dataProvider().capabilities()
#voir si la couche vecteur est modifiable
if caps & QgsVectorDataProvider.DeleteFeatures:
print('C\'est possible')
else :
print('Pas possible')
#Renvoie : "C'est possible"
XLctrl=Lctrl.dataProvider().fields()[0]
caps = Lctrl.dataProvider().capabilities()
Lctrl.startEditing() #ouvrir mode édition de Listing Ctrl
# je fais sans problème les suppressions et ajouts de champs via le dataprovider
if caps & QgsVectorDataProvider.DeleteAttributes:
Lctrl.dataProvider().deleteAttributes([3])
Lctrl.dataProvider().addAttributes([QgsField("Alors", QVariant.String)])
AlorsLctrl=Lctrl.dataProvider().fieldNameIndex("Alors")
fid = 10
valeur = 'Bien joué'
# j'ai réussi à faire la modif via getFeature mais sur un seul objet : fid = 10,
comme décrit dans le cookbook
Lctrl.changeAttributeValue(fid, AlorsLctrl, valeur)
Lctrl.commitChanges()
-----------------
je peux aussi le faire via le data provider (j'ai trouvé la solution en rédigeant ce
post):
-----------------
Code :
Lctrl.startEditing() #ouvrir mode édition de Listing Ctrl
if caps & QgsVectorDataProvider.DeleteAttributes:
Lctrl.dataProvider().deleteAttributes([3])
Lctrl.dataProvider().addAttributes([QgsField("Alors", QVariant.String)])
AlorsLctrl=Lctrl.dataProvider().fieldNameIndex("Alors")
fid = 15
attrib = {3:"Bien joué"}
Lctrl.dataProvider().changeAttributeValues({fid : attrib})
Lctrl.commitChanges()
-----------------
J'ai cherché comment remplacer l'argument 'fid' par un symbole ou une
formule qui dirait 'pour tous les objets/id', pour que tous aient la valeur
'Bien joué', mais je n'ai pas trouvé, c'est surement très simple pour
certains d'entre vous...
J'avais essayé d'inclure les deux façons de faire dans une boucle mais sans
réussir non plus.
un truc du style :
-----------------
Code :
fid = 15
attrib = {3:"Bien joué"}
for objet in Lctrl.dataProvider():
Lctrl.dataProvider.changeAttributeValues({fid : attrib})
-----------------
D'ailleurs existe -t-il un glossaire des erreurs qui aiguille sur ce qui bloque, ce
qu'il faut corriger : "not iterable", has no attribute", etc... ?
Dans le cook book, je n'arrive pas à comprendre la différence entre :
page 24
-----------------
Code :
if caps & QgsVectorDataProvider.ChangeAttributeValues:
attrs = { 0 : "hello", 1 : 123 }
layer.dataProvider().changeAttributeValues({ fid : attrs })
-----------------
et page 25
-----------------
Code :
layer.changeAttributeValue(fid, fieldIndex, value)
-----------------
si ce n'est qu'il y a une histoire de undo/redo, mais c'est une autre
question...
Je récapitule mes principales questions :
Existe -t-il un 'glossaire des erreurs' qui puisse aiguiller sur ce qui bloque, ce
qu'il faut corriger : lors des "not iterable", has no attribute",
etc... ?
Y a t il un symbole ou une formule en code python pour dire 'pour tous les
objets/id' ou 'sur toutes les lignes' ?
Est ce que quelqu'un pourrait m'indiquer comment corriger la boucle SVP ?
Je vous remercie beaucoup d'avoir lu jusque là, et encore plus si vous avez des pistes
ou réponses à certaines questions.
Bien cordialement,
F.DUVAL
----------------------------------------
Le message est situé
https://georezo.net/forum/viewtopic.php?pid=329474#p329474
Pour y répondre : qgis_fr(a)ml.georezo.net ou reply de votre messagerie
Pour vous désabonner connectez-vous sur le forum puis Profil / Abonnement
--
Association GeoRezo - le portail géomatique
https://georezo.net