<div dir="ltr"><div><div><div><div><div>Hi all,<br><br></div>Improve version here:<br><a href="https://gist.github.com/mdouchin/72a09b629a5557c1dc1c">https://gist.github.com/mdouchin/72a09b629a5557c1dc1c</a> <br><br>with:<br></div><br>* "replayed" variable to avoid probable infinite loop, thanks to Hugo's proposal<br></div><br>* you can now initialize the method with a python list of scales you want to force canvas to:  <br><br>fs =  fs = forcedScale( [25000, 50000, 100000 ] )<br><br></div>Cheers,<br></div>Michaël<br></div><div class="gmail_extra"><br><div class="gmail_quote">2015-04-17 12:27 GMT+02:00 kimaidou <span dir="ltr"><<a href="mailto:kimaidou@gmail.com" target="_blank">kimaidou@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Hi Hugo,<br><br></div>Thanks for the anwser. I used some "print scale" and "print targetScale" in my script to check the behavious, and I did not have any "infinite loop" or strange behaviour with it. It seems the related QGIS code is armed against this risks.<br></div><div><br>This python script was only a prototype, and I will surely have a look at the cpp classes and propose a PR to add this option in QGIS core.<br></div><br></div>Michaël<br></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">2015-04-17 11:26 GMT+02:00 Hugo Mercier <span dir="ltr"><<a href="mailto:hugo.mercier@oslandia.com" target="_blank">hugo.mercier@oslandia.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<span><br>
Le 17/04/2015 10:46, kimaidou a écrit :<br>
> Hi QGIS !<br>
><br>
> I would like to be able in QGIS to force the canvas scales to some<br>
> predefined ones. Since we now have project scales (and QGIS pre-defined<br>
> scales) in the scale selector, we could use them, and add a simple<br>
> checkbox near the combobox "Stick to predefined scales".<br>
><br>
> The aim is to force the canvas to render only at these scales. For<br>
> example, if I use the rectangle zoom tool, and I should go toe 1/56003,<br>
> I would instead land on 1/50000 , the closest pre-defined scale.<br>
<br>
</span>That would be nice to have it in the core. I already had to do something<br>
similar with a plugin.<br>
<span><br>
><br>
> I made a little python script as a proof of concept to illustrate it :<br>
> <a href="http://paste.debian.net/167247/" target="_blank">http://paste.debian.net/167247/</a><br>
><br>
> In this script, I hard coded the scales, but oviously we should get them<br>
> from the project properties.<br>
><br>
> I have a question regarding my script. Since I use the<br>
> QgsMapCanvas::scaleChanged signal, I assume the rendering is done twice<br>
> ? Once the "normal" way, and once again after I use the<br>
> QgsMapCanvas::zoomScale method after calculating the new target scale.<br>
><br>
> Any idea for improving it ? I assume I would have to disconnect one (not<br>
> found yet) signal/slot, then set the scale and reconnect this<br>
> signal/slot afterwards ?<br>
<br>
</span>QObject::blockSignals might be of help here. But in this case, you don't<br>
want to block all signals, only yours.<br>
<br>
I guess your solution would work.<br>
You can also use a flag in your callback, something like :<br>
<br>
    def setScale( self, scale ):<br>
        if self.reentrant:<br>
                return<br>
<br>
        targetScale = min(<br>
            self.predefinedScales,<br>
            key=lambda x:abs(x-scale)<br>
        )<br>
        self.reentrant = True<br>
        self.mc.zoomScale( targetScale )<br>
        self.reentrant = False<br>
<br>
_______________________________________________<br>
Qgis-developer mailing list<br>
<a href="mailto:Qgis-developer@lists.osgeo.org" target="_blank">Qgis-developer@lists.osgeo.org</a><br>
<a href="http://lists.osgeo.org/mailman/listinfo/qgis-developer" target="_blank">http://lists.osgeo.org/mailman/listinfo/qgis-developer</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>