Skip to content

Instantly share code, notes, and snippets.

@kgjenkins
Last active November 30, 2022 09:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kgjenkins/29f8dd4e7da3cba3e0acbdc72844748a to your computer and use it in GitHub Desktop.
Save kgjenkins/29f8dd4e7da3cba3e0acbdc72844748a to your computer and use it in GitHub Desktop.
QGIS Python to automatically update layer from data source

The following Python code will, every 30 seconds, automatically update the data from the source for any QGIS layer with 'autoUpdate' in the layer name. Each time it updates, it will put the timestamp in the layer name, although you could leave that part out.

This is particularly useful for remote data sources like json-over-http or even local CSV files that might be changed by another program while the QGIS project is open.

Just paste the code into the QGIS Python console.

import threading
import datetime
import re

def autoUpdateLayers():
  threading.Timer(30.0, autoUpdateLayers).start()
  for layer in QgsProject.instance().mapLayers().values():
    if 'autoUpdate' in layer.name():
      print('autoUpdating layer: '+layer.name())
      layer.dataProvider().forceReload()
      layer.setName(
        re.sub(
          'autoUpdate.*',
          'autoUpdated ' + datetime.datetime.now().strftime('%c'),
          layer.name()
        )
      )

autoUpdateLayers()

CC0 "No Rights Reserved" So feel free to use, modify, or do whatever you want with this code.

@sigurdbengtson
Copy link

Thanks for the bit of code.

When does the .Timer() stop? When the project i close/re-opened?

@kgjenkins
Copy link
Author

kgjenkins commented Nov 29, 2022

I don't even recall writing this code, but I guess I did... so good question, @SBENGSDFI !

I think the Timer will continue to run until you close QGIS. Also, if you are just running the code in the Python console, it won't automatically be included as part of a saved project, so you would have to run it again manually in the console.

If you wanted it to automatically run when you open a project, you could set it up as a macro in the QGIS project properties > Macros tab, and then add it something like this:

from qgis.core import QgsProject
import threading
import datetime
import re

def autoUpdateLayers():
  threading.Timer(30.0, autoUpdateLayers).start()
  for layer in QgsProject.instance().mapLayers().values():
    if 'autoUpdate' in layer.name():
      print('autoUpdating layer: '+layer.name())
      layer.dataProvider().forceReload()
      layer.setName(
        re.sub(
          'autoUpdate.*',
          'autoUpdated ' + datetime.datetime.now().strftime('%c'),
          layer.name()
        )
      )

def openProject():
    autoUpdateLayers()

def saveProject():
    pass

def closeProject():
    pass

I'll admit that I haven't really used python's Timer object except for this code snippet. But it looks like it has a cancel() method you could use.

Also, this whole thing seems to be unnecessary with local files. I just tested with a local CSV, and it seems to instantly update automatically, even without enabling the "Watch file" option when adding a delimited text layer.

@sigurdbengtson
Copy link

Yeah I only saw the date for your latest post after commenting. But thanks for the answer!

It worked as a nice quick solution for me to use with some layers i access via a postgres database. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment