Libération des verrous de fichiers PyQGIS?

16

Je me demandais ce qui déclenche la libération des verrous de fichiers dans pyQGIS?

J'essaie de supprimer quelques sources de données (utilisées temporairement) en appelant QgsVectorFileWriter.deleteShapeFile, mais je dois quitter QGIS avant de pouvoir le faire. J'ai chargé les sources dans des objets QgsVectorLayer. Tous ces objets et leurs références doivent-ils être récupérés avant de pouvoir supprimer la source? Y a-t-il un moyen de forcer cela?


J'ai réussi à créer un exemple de code minimal qui échoue. Assurez-vous que le répertoire temp est vide avant d'exécuter.

from qgis.core import *
import processing, os, gc

project_temp_dir = "C:/Path/To/My/Dir/"      
layer1_path = project_temp_dir + "layer1.shp"
layer2_path = project_temp_dir + "layer2.shp"
input_layer = QgsMapLayerRegistry.instance().mapLayersByName('in_layer')[0]
if not input_layer.isValid(): raise Exception("Failed to grab input layer")

# Create layer 1
err = QgsVectorFileWriter.writeAsVectorFormat(input_layer, layer1_path, "utf-8", input_layer.crs())   
if err != QgsVectorFileWriter.NoError: raise Exception("Failed to write layer 1")

# Load layer 1
layer1 = QgsVectorLayer(layer1_path, "lyr1", "ogr")
if not layer1.isValid(): raise Exception("Failed to load layer 1")

# Use layer 1 to create layer 2, read-only makes no difference
# if not layer1.setReadOnly(): raise Exception("Could not set layer 1 to read-only")
processing.runalg("qgis:reprojectlayer", layer1, "EPSG:54030", layer2_path)

# Load layer 2
layer2 = QgsVectorLayer(layer2_path, "lyr2", "ogr")
if not layer2.isValid(): raise Exception("Failed to load layer 2")

del layer1
del layer2 
del input_layer
gc.collect()
print "Garbage: " + str(gc.garbage) # Empty

# Remove data sources for layers - FAILS!!
for f in os.listdir(project_temp_dir):          
    if f.endswith(".shp") and not os.path.isdir(project_temp_dir + f):              
        if not QgsVectorFileWriter.deleteShapeFile(project_temp_dir + f):
            # F*%&ing locks. 
            print "Failed to clear project temp directory."

J'ai trouvé que cela fonctionne si j'utilise QgsVectorFileWriterpour créer layer2, au lieu de l'algorithme de traitement. J'obtiens la même erreur si j'essaye l' qgis:clipalgorithme. Est-ce donc un bug dans le traitement? Suis-je mal utilisé?

Oystein
la source

Réponses:

9

Désolé de continuer à répondre à mes propres questions, mais je pense avoir trouvé une solution.

Il s'avère que cela fonctionne bien si vous ajoutez la couche au registre de carte, puis la supprimez à nouveau. Le registre de carte prend possession de la couche. Ainsi, lorsqu'il est supprimé du registre, les verrous sont libérés. Notez que vous devez ajouter le calque à la légende ( .addMapLayer(layer, addToLegend = False) ne fonctionnera pas).

Vous ne savez toujours pas s'il faut appeler cela une solution ou une solution de contournement, mais cela fait le travail.

# ...

# Replace the following code (note: should do error checking on map registry functions):

# Load layer 1
layer1 = QgsVectorLayer(layer1_path, "lyr1", "ogr")
if not layer1.isValid(): raise Exception("Failed to load layer 1")
QgsMapLayerRegistry.instance().addMapLayer(layer1) #!!!!

# Use layer 1 to create layer 2  
processing.runalg("qgis:reprojectlayer", layer1, "EPSG:54030", layer2_path)

# Load layer 2
layer2 = QgsVectorLayer(layer2_path, "lyr2", "ogr")
if not layer2.isValid(): raise Exception("Failed to load layer 2")
QgsMapLayerRegistry.instance().addMapLayer(layer2) #!!!!

# Remove layer references
QgsMapLayerRegistry.instance().removeMapLayer(layer1.id()) #!!!!
QgsMapLayerRegistry.instance().removeMapLayer(layer2.id()) #!!!!

# Remove data sources for layers
for f in os.listdir(project_temp_dir):          
    if f.endswith(".shp") and not os.path.isdir(project_temp_dir + f):    
    # ...

Si quelqu'un a plus d'informations, je serais heureux d'en savoir plus à ce sujet.

Oystein
la source
je dois supprimer deux de ces couches ... je suis capable de supprimer un en utilisant la méthode ci-dessus .. tous les autres fichiers à l'exception de .dbf et .shp du second sont supprimés .. y a-t-il une solution pour supprimer ces deux fichiers ainsi que?
rao