1

On Windows 11 I have a PyQGIS script that creates layers from gpkg files. This all works perfectly fine.

I want to delete these layers, recreate the gpkg files and reload them as layers again and this is where it comes unstuck.

Let's say I have two gpkg layers in my project, layer1.gpkg and layer2.gpkg.

When I open the QGIS project, I see in the windows file handles, there are 2 file handles open for each layer file.

If I manually remove layer1 from the project (right click - remove layer) and then check the file handles, oddly I will be left with just a single open file handle for layer2.gpkg.

If I then use the script to add layer1.gpkg and check the file handles, I am back to 2 file handles open for each layer.

If I then delete layer1 using my script (and leave it running), I see 2 file handles for layer2 and 1 file handle for layer1 left open.

This remaining open file handle for layer1.gpkg stops me from overwriting the file, and that is my problem.

I am removing layer1 like this:

QgsProject.instance().removeMapLayer(layer1.layerId())
QgsProject.instance().reloadAllLayers()
iface.mapCanvas().refresh() # Just in case
gc.collect() # Just in case

This removes the layer in the tree but leaves one open file handle on the file. As opposed to removing the file using the "Remove Layer" menu item, which leaves no file handles open on the file.

The only thing I see in the API documentation is the removeMapLayer marks the project dirty, but it seems there must be some other housekeeping that needs to be done to release that other file handle from the OS.

1 Answer 1

0

You might need to provide more of your code -- specifically, where are you attempting to overwrite the file.

At first glance, I suspect that the reason the file is remaining open is that calling removeMapLayer removes the layer from the project, but does not delete the layer from memory because the layer1 variable is maintaining a reference to the underlying QgsVectorLayer object. As long as layer1 has not gone out of scope, that layer object will not be garbage collected. You can try calling del layer1 before you call gc.collect() and see if that helps.

3
  • I am assuming that once the python script ends, anything it had open should be released. I have added the delete and garbage collection as suggested, but to no avail. I suspect that the problem may be with how the API code is processing the request and that code is not releasing the file handles.
    – John_nz
    Commented Jul 14 at 23:10
  • Do these layers have relations to each other?
    – couteau
    Commented Jul 15 at 2:20
  • They are both children of a group. I delete each child layer and then the group. Comparing with deleting the group via the UI, via the UI the child layers and group are deleted leaving no residual file handles open.
    – John_nz
    Commented Jul 16 at 4:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.