Thursday 24 May 2018

pyqgis - QGIS doesn't update some snapping options from Python


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.



Answer



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...


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...