5

I am trying to create plugin that will open new window with some layer, Dynamically "pan" my window, when main window is pan. So boundingbox coordinates should be the same in both windows.
I need new window to move with main QGIS window. I've found out in documentation useful code for map canvas:

import sys, os
class MyWnd(QMainWindow):
 def __init__(self, layer):
 QMainWindow.__init__(self)
 self.canvas = QgsMapCanvas()
 self.canvas.setCanvasColor(QtCore.Qt.white)
 self.canvas.setExtent(layer.extent())
 self.canvas.setLayerSet([QgsMapCanvasLayer(layer)])
 self.setCentralWidget(self.canvas)
 actionZoomIn = QAction("Zoom in", self)
 actionZoomOut = QAction("Zoom out", self)
 actionPan = QAction("Pan", self)
 actionZoomIn.setCheckable(True)
 actionZoomOut.setCheckable(True)
 actionPan.setCheckable(True)
 self.connect(actionZoomIn, QtCore.SIGNAL("triggered()"), self.zoomIn)
 self.connect(actionZoomOut, QtCore.SIGNAL("triggered()"), self.zoomOut)
 self.connect(actionPan, QtCore.SIGNAL("triggered()"), self.pan)
 self.toolbar = self.addToolBar("Canvas actions") 
 self.toolbar.addAction(actionZoomIn)
 self.toolbar.addAction(actionZoomOut)
 self.toolbar.addAction(actionPan)
 # create the map tools
 self.toolPan = QgsMapToolPan(self.canvas)
 self.toolPan.setAction(actionPan)
 self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
 self.toolZoomIn.setAction(actionZoomIn)
 self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
 self.toolZoomOut.setAction(actionZoomOut)
 self.pan()
 def zoomIn(self):
 self.canvas.setMapTool(self.toolZoomIn)
 def zoomOut(self):
 self.canvas.setMapTool(self.toolZoomOut)
 def pan(self):
 self.canvas.setMapTool(self.toolPan)

And using class below I get coordinates from main canvas and set coordinates to my canvas (part of QGIS plugin):

def run(self):
 """Run method"""
 import re
 wnd = MyWnd(self.iface.activeLayer())
 wnd.show()
 canv = qgis.utils.iface.mapCanvas()
 coords = canv.mapRenderer().extent().toString()
 coords = re.findall("([0-9]*\.[0-9]*)", coords)
 wnd.canvas.setExtent(QgsRectangle(float(coords[0]), float(coords[1]), float(coords[2]),float(coords[3])))
 wnd.canvas.refresh()

I think this part of code can be used in loop (if coordinates change - I will set new coordinates in own canvas). But I don't sure if it is a good way.
Is there any other way to solve this issue? Provide me with right way, please.

asked Jun 24, 2016 at 16:10

1 Answer 1

6

When a canvas changes its extent a extentsChanged signal is emitted. When you connect this signal to a method (called slot), then you are able to run this method whenever the extent changes.

To deploy this mechanism I altered your code in the following way.

# Declare a global variable to hold the reference to QGIS canvas
canv = None
# here comes your class definition
class MyWnd(QMainWindow):
 def __init__(self, layer):
 # ...
 self.show()
 # ...
 # new method to sync both canvases
 def sync(self):
 global canv
 self.canvas.setExtent(canv.extent())
 self.canvas.refresh()
# next lines would go into your run(), to run them at python console
# put them in the main code block
canv = iface.mapCanvas()
layer = iface.activeLayer()
wnd = MyWnd(layer)
canv.extentsChanged.connect(wnd.sync)

Now, when you change the extent of mapcanvas in Qgis, extent of your new window changes accordingly. Don't forget to disconnect the signal when your plugin stops working.

answered Jun 25, 2016 at 12:18
2
  • Thank you a lot. Could you help me again, please? I've added sync method + global var canv to MyWnd class and code above to run method. But new window has disappeared instantly after I press plugin button. What I do wrong? Commented Jun 27, 2016 at 9:02
  • I think this a to general question, and is off topic of this question here. Post it as a new question providing more details of the initialization of your plugin. If you like you may send me your script and I will have a look. Commented Jul 5, 2016 at 17:44

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.