2

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.

2

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.

  • 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? – Davion Jun 27 '16 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. – Detlev Jul 5 '16 at 17:44

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.