5

I've just installed QGIS 2.14.3 (Essen) on a Windows 7 machine, so I've got the default configuration on everything. This means that under "Settings -> Options -> Digitizing", I've got "Default snap mode = Off", and "Default snapping tolerance = 0,00000 map units".

When I create a new project, and then create a new multipolygon temporary scratch layer, snapping mode is off as expected according to the general digitizing options previosly described. This can be verified under "Settings -> Snapping options", or just by creating a new feature and checking that its vertex don't snap.

After that, from the Python console I type the following:

>>> proj=QgsProject.instance()
>>> proj.readEntry('Digitizing','DefaultSnapType')
(u'off', True)

So, until now, everything seems to be OK because Python shows the same information that the GUI.

But, if I type:

>>> proj.writeEntry('Digitizing','DefaultSnapType', 'to vertex and segment')
True
>>> proj.writeEntry('Digitizing','DefaultSnapTolerance', 10.0)
True

It looks like I've changed the snapping mode, but actually QGIS hasn't changed it at all. In fact, if I go to "Settings -> Snapping options" it shows "Snap to = Off", and "Tolerance = 0". But, If I type:

>>> proj.readEntry('Digitizing','DefaultSnapType')
(u'to vertex and segment', True)
>>> proj.readNumEntry('Digitizing','DefaultSnapTolerance')
10

So the GUI and the Python console show different information, but only the GUI's options are the real ones.

Then, if I change the "Snap to" option on the GUI to "To segment and vertex", "Tolerance = 10", and click OK, then QGIS has really activated the snapping mode. I mean, if I create a new feature its vertex will snap properly.

It would seem at first sight that you cannot change snapping option from the console, but this is not totally true, because if I type:

>>> proj.writeEntry('Digitizing', 'TopologicalEditing', 1) 
True
>>> proj.writeEntry('Digitizing', 'IntersectionSnapping', True) 
True

The GUI options "Enable topological editing" and "Enable snapping on intersection" get activated. And in the same way, I can really deactivate both options (I mean, showing properly deactivated on "Settings -> Snapping options") by typing:

>>> proj.writeEntry('Digitizing', 'TopologicalEditing', 0) 
True
>>> proj.writeEntry('Digitizing', 'IntersectionSnapping', False) 
True

In conclusion, it looks like QGIS doesn't really update all snapping settings from Python, but only some of them, so you've got to use the GUI if you want to change them all.

Does anybody know a workaround?

If not, can somebody try to reproduce the situation and tell me their results? I'd like to know if someone else is suffering this issue before I report it like a bug.

3

If you want to update the options you see in Settings > Snapping Options..., you can use the setSnapSettingsForLayer() function from the QgsProject Class:

proj=QgsProject.instance()
layer = qgis.utils.iface.activeLayer()
proj.setSnapSettingsForLayer(layer.id(), True, 0, 1, 10, True)

Note that although you're using the active layer to set the snapping options, this will apply to all layers in your project.


Interestingly, your method does not update any GUI options in Settings > Options > Digitizing > Snapping nor in Settings > Options > Advanced> Qgis > digitizing. But if you use the following, these GUI options will be updated but not in Settings > Snapping Options:

from PyQt4.QtCore import QSettings
QSettings().setValue('QGIS/digitizing/default_snap_mode', 'to vertex and segment')
QSettings().setValue('QGIS/digitizing/default_snapping_tolerance', 10)

But I'm not in a position to say whether or not it's a bug.



EDIT:

I am also using QGIS 2.14.3-Essen for Win7 64-bit.

I did some more testing also, it seems that for me atleast, the Settings > Snapping Options... interface only gets updated when I either use the setSnapSettingsForLayer class or close the interface and open it again. This includes testing the checkboxes the same way you have done.

Therefore, if you want to use the advanced snapping options, try:

proj = QgsProject.instance()
proj.writeEntry('Digitizing', 'SnappingMode', 'advanced') 
layer = qgis.utils.iface.activeLayer()
proj.setSnapSettingsForLayer(layer.id(), True, 0, 1, 30, True)

Note that you will need to select each layer and run the last 2 lines to update the settings in the advanced interface.

It seems that the setSnapSettingsForLayer class only registers when using the advanced snapping options because if you use the following for either current_layer and all_layers, any values set using the setSnapSettingsForLayer class seems to be ignored but the interface will be updated with the values you set using proj.writeEntry():

proj = QgsProject.instance()
proj.writeEntry('Digitizing', 'SnappingMode', 'all_layers') 
proj.writeEntry('Digitizing','DefaultSnapTolerance', 25.0)
layer = qgis.utils.iface.activeLayer()
proj.setSnapSettingsForLayer(layer.id(), True, 0, 0, 0, True)

Because now if I type the following like you have done:

>>> proj.readNumEntry('Digitizing','DefaultSnapTolerance')
25

Weird behavour...

  • @J.G. - Most welcome, glad it works :) – Joseph Jul 7 '16 at 10:27
1

Thank you for your answer Joseph, but I'm afraid that I cannot reproduce some of your results. By the way, what version of QGIS and OS are you using?

If I type your first code snippet my GUI doesn't get updated, unless I've got "Settings -> Snapping options -> Snapping mode = Advanced".

Regarding to my method, I can actually use it to change two checkboxes on the fly at "Settings -> Snapping options" (if you've got "Snapping mode" set to "All layers" or "Current Layer"), which are "Enable topological editing" and "Enable snapping on intersection". Doesn't it work for you like that?

Your second code example sets the QGIS global preferences (under "Settings -> Options -> Digitizing"), which seem to be overridden by "Settings -> Snapping options".

Therefore, I'd need a method to change "Settings -> Snapping options -> Snapping mode" to "Advanced", so I could use your first code, but I cannot find one. I've tried the following:

>>> proj.writeEntry('Digitizing', 'SnappingMode', 'advanced') 
True
>>> proj.readEntry('Digitizing', 'SnappingMode') 
(u'advanced', True)

But unfortunately I've got the same results as on my first post, the project parameters get updated on memory, but not on the GUI so they don't take effect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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