1

I have a written a python-script below which creates a vector grid based on the resolution of a .tif image (satellite imagery).

import processing

layer = iface.activeLayer()

#define parameters for the qgis vectorgrid algorithm
xmin = (layer.extent().xMinimum())
xmax = (layer.extent().xMaximum())
ymin = (layer.extent().yMinimum())
ymax = (layer.extent().yMaximum())
extent = "{0},{1},{2},{3}".format(xmin,xmax,ymin,ymax)
pix_xy= (layer.rasterUnitsPerPixelX() + layer.rasterUnitsPerPixelY())/2
gridsize = (((layer.width() + layer.height())*pix_xy)/2)/8

#create grid
processing.runandload('qgis:vectorgrid',
                  extent,
                  gridsize,
                  gridsize,
                  0,
                  None)

This vector grid contains an attribute table with, among other things, an ID field.

I would like to navigate through the vector grid cells/feature by keyboard arrows (or other keys). For example if down key is pressed, it selects the vector gridcell/feature below. I have no clue how to do this in the Python console.

I'm working with QGIS 2.18.14

  • Welcome to gis.stackexchange! Please note that a good question on this site is expected to show some degree of research on your part, i.e. what you have tried and relevant code so far. What have you tried to achieve keyboard interactivity? For more info, you can check our faq. – underdark Nov 28 '17 at 17:26
  • This is not possible,you need override keyPressEvent function in a mapCanvas for this qgis.org/api/… – Fran Raga Nov 29 '17 at 15:09
1

I manage to navigate through the vector grid using the QShortcut and QKeySequence classes from PyQt4.QtGui. The codes below only works with the QGIS vector grid algorithm product. When the script is executed, it will connect the navigation functions with a specific keyboard key. There is a bug: if you run the script again it will terminate the navigation functions and you have to re-start QGIS to use the functions again.

#Navigation
from PyQt4.QtGui import QShortcut, QKeySequence
from PyQt4.QtCore import Qt

#get vector grid 
for layer in iface.legendInterface().layers():
    if layer.name() == "Grid":
        grid = layer
    else:
        pass

#function to get selected id
def get_id():
    id = grid.selectedFeatures()[0]
    selected = int(id.attributes()[0])
    return selected

#forward function
def forward():
    #add 1 to every selected id
    next_cursor = get_id() + 1

    #select the the id from next_cursor as selection
    expr = QgsExpression("\"id\" = '{} '".format(next_cursor))
    it = grid.getFeatures(QgsFeatureRequest(expr))
    ids = [i.id() for i in it]
    grid.setSelectedFeatures(ids)

    #zoom to selected id
    canvas = iface.mapCanvas()
    canvas.zoomToSelected()
    canvas.zoomByFactor(2)

 #backward function
 def backward():
     #add 1 to every selected id
     next_cursor = get_id() - 1

     #select the the id from next_cursor as selection
     expr = QgsExpression("\"id\" = '{} '".format(next_cursor))
     it = grid.getFeatures(QgsFeatureRequest(expr))
     ids = [i.id() for i in it]
     grid.setSelectedFeatures(ids)

    #zoom to selected id
    canvas = iface.mapCanvas()
    canvas.zoomToSelected()
    canvas.zoomByFactor(2)

  #backward function
  def downward():
      #add 1 to every selected id
      next_cursor = get_id() + col

      #select the the id from next_cursor as selection
      expr = QgsExpression("\"id\" = '{} '".format(next_cursor))
     it = grid.getFeatures(QgsFeatureRequest(expr))
     ids = [i.id() for i in it]
     grid.setSelectedFeatures(ids)

     #zoom to selected id
     canvas = iface.mapCanvas()
     canvas.zoomToSelected()
     canvas.zoomByFactor(2)

 #backward function
 def upward():
     #add 1 to every selected id
     next_cursor = get_id() - col

     #select the the id from next_cursor as selection
     expr = QgsExpression("\"id\" = '{} '".format(next_cursor))
     it = grid.getFeatures(QgsFeatureRequest(expr))
     ids = [i.id() for i in it]
     grid.setSelectedFeatures(ids)

     #zoom to selected id
     canvas = iface.mapCanvas()
     canvas.zoomToSelected()
     canvas.zoomByFactor(2)

#connect forward() function with the D button
shortcut = QShortcut(QKeySequence(Qt.Key_D),iface.mainWindow())
shortcut.setContext(Qt.ApplicationShortcut)
shortcut.activated.connect(forward)

#connect backward() function with the A button
shortcut = QShortcut(QKeySequence(Qt.Key_A),iface.mainWindow())
shortcut.setContext(Qt.ApplicationShortcut)
shortcut.activated.connect(backward)

#connect downward() function with the S button
shortcut = QShortcut(QKeySequence(Qt.Key_S),iface.mainWindow())
shortcut.setContext(Qt.ApplicationShortcut)
shortcut.activated.connect(downward)

#connect upward() function with the W button
shortcut = QShortcut(QKeySequence(Qt.Key_W),iface.mainWindow())
shortcut.setContext(Qt.ApplicationShortcut)
shortcut.activated.connect(upward)

PS: there is a lot of repetition, sorry for that. I'm still learning Python.

  • Nice work! If you're worried about repetition, you could post a question over to CodeReview:SE for advice on how to make your code more concise :) – Joseph Dec 12 '17 at 10:12

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.