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.
1 Answer 1
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 varcanv
toMyWnd
class and code above torun
method. But new window has disappeared instantly after I press plugin button. What I do wrong?Davion– Davion2016年06月27日 09:02:55 +00:00Commented 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.Detlev– Detlev2016年07月05日 17:44:23 +00:00Commented Jul 5, 2016 at 17:44
Explore related questions
See similar questions with these tags.