I want to display data based on the feature currently selected/clicked on.
I am following a tutorial from http://www.qgisworkshop.org/html/workshop/plugins_tutorial.html.
It initially shows you how to use the Textbrowser to display the coordinates currently clicked on and developing that functionality further, it allows you to see the information regarding a respective feature.
I have the following function which as per example in the above mentioned tutorial is set to retrieve the respective data. In the example it refers to the field name "NAME" which from what I can understand refers to the name of the field in the attribute table for the respective layer in question.
My attribute table structure is as follows:
field names:
objectid str_add_id building_number building_name_id street_name_id etc etc
The field I wish to retrieve is that of the "str_add_id" therefore using his example in the tutorial:
His Example:
def updateTextBrowser(self):
# if we have a selected feature
if self.selectList:
# find the index of the 'NAME' column, branch if has one or not
nIndx = self.provider.fieldNameIndex('NAME')
# get our selected feature from the provider, but we have to pass in an empty feature and the column index we want
sFeat = QgsFeature()
if self.provider.featureAtId(self.selectList[0], sFeat, True, [nIndx]):
# only if we have a 'NAME' column
if nIndx != -1:
# get the feature attributeMap
attMap = sFeat.attributeMap()
# clear old TextBrowser values
self.dlg.clearTextBrowser()
# now update the TextBrowser with attributeMap[nameColumnIndex]
# when we first retrieve the value of 'NAME' it comes as a QString so we have to cast it to a Python string
self.dlg.setTextBrowser( str( attMap[nIndx].toString() ))
In my example, I basically replaced the nIndx = self.provider.fieldNameIndex('NAME') changing the "'NAME'" to "'str_add_id'".
Unfortunately however upon clicking on the feature I do not get the requested data. I still receive the X and Y coordinates of the point clicked on in the layer.
Any ideas as to what I could be doing wrong? I have attached my whole plugin code below:
# -*- coding: utf-8 -*-
"""
/***************************************************************************
testplug
A QGIS plugin
Test plugin through builder
-------------------
begin : 2013-05-08
copyright : (C) 2013 by Test
email : [email protected]
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
# Import the PyQt and QGIS libraries
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
# Initialize Qt resources from file resources.py
import resources
# Import the code for the dialog
from testplugdialog import testplugDialog
class testplug:
def __init__(self, iface):
# Save reference to the QGIS interface
self.iface = iface
#A reference to our map canvas
self.canvas = self.iface.mapCanvas()
#Change
# this QGIS tool emits as QgsPoint after each click on the map canvas
self.clickTool = QgsMapToolEmitPoint(self.canvas)
# create our GUI dialog
self.dlg = testplugDialog()
# create a list to hold our selected feature ids
self.selectList = []
# current layer ref (set in handleLayerChange)
self.cLayer = None
# current layer dataProvider ref (set in handleLayerChange)
self.provider = None
# initialize plugin directory
self.plugin_dir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins/testplug"
# initialize locale
localePath = ""
locale = QSettings().value("locale/userLocale").toString()[0:2]
if QFileInfo(self.plugin_dir).exists():
localePath = self.plugin_dir + "/i18n/testplug_" + locale + ".qm"
if QFileInfo(localePath).exists():
self.translator = QTranslator()
self.translator.load(localePath)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
# Create the dialog (after translation) and keep reference
self.dlg = testplugDialog()
def initGui(self):
# Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/testplug/icon.png"),
u"Test Plugin through builder", self.iface.mainWindow())
# connect the action to the run method
QObject.connect(self.action, SIGNAL("triggered()"), self.run)
# Add toolbar button and menu item
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToMenu(u"&testplug", self.action)
# connect our custom function to a clickTool signal that the canvas was clicked
#result = QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.handleMouseDown)
#QMessageBox.information( self.iface.mainWindow(),"Info", "connect = %s"%str(result) )
# connect our select function to the canvasClicked signal
#result = QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.selectFeature)
#QMessageBox.information( self.iface.mainWindow(),"Info", "connect = %s"%str(result) )
QObject.connect(self.dlg.ui.chkActivate,SIGNAL("stateChanged(int)"),self.changeActive)
# connect to the currentLayerChanged signal of QgsInterface
result = QObject.connect(self.iface, SIGNAL("currentLayerChanged(QgsMapLayer *)"), self.handleLayerChange)
# QMessageBox.information( self.iface.mainWindow(),"Info", "connect = %s"%str(result) )
def handleLayerChange(self, layer):
self.cLayer = self.canvas.currentLayer()
if self.cLayer:
self.provider = self.cLayer.dataProvider()
def changeActive(self,state):
if (state==Qt.Checked):
# connect to click signal
QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.handleMouseDown)
# connect our select function to the canvasClicked signal
QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.selectFeature)
else:
# disconnect from click signal
QObject.disconnect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.handleMouseDown)
# disconnect our select function to the canvasClicked signal
QObject.disconnect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.selectFeature)
def unload(self):
# Remove the plugin menu item and icon
self.iface.removePluginMenu(u"&testplug", self.action)
self.iface.removeToolBarIcon(self.action)
def handleMouseDown(self, point, button):
self.dlg.clearTextBrowser()
self.dlg.setTextBrowser( str(point.x()) + " , " +str(point.y()) )
#QMessageBox.information( self.iface.mainWindow(),"Info", "X,Y = %s,%s" % (str(point.x()),str(point.y())) )
def selectFeature(self, point, button):
# QMessageBox.information( self.iface.mainWindow(),"Info", "in selectFeature function" )
# setup the provider select to filter results based on a rectangle
pntGeom = QgsGeometry.fromPoint(point)
# scale-dependent buffer of 2 pixels-worth of map units
pntBuff = pntGeom.buffer( (self.canvas.mapUnitsPerPixel() * 2),0)
rect = pntBuff.boundingBox()
# get currentLayer and dataProvider
self.cLayer = self.canvas.currentLayer()
self.selectList = []
if self.cLayer:
self.provider = self.cLayer.dataProvider()
feat = QgsFeature()
# create the select statement
self.provider.select([],rect) # the arguments mean no attributes returned, and do a bbox filter with our buffered rectangle to limit the amount of features
while self.provider.nextFeature(feat):
# if the feat geom returned from the selection intersects our point then put it in a list
if feat.geometry().intersects(pntGeom):
self.selectList.append(feat.id())
if self.selectList:
# make the actual selection
self.cLayer.setSelectedFeatures(self.selectList)
# update the TextBrowser
self.updateTextBrowser()
else:
QMessageBox.information( self.iface.mainWindow(),"Info", "No layer currently selected in TOC" )
def updateTextBrowser(self):
# if we have a selected feature
if self.selectList:
# find the index of the 'NAME' column, branch if has one or not
nIndx = self.provider.fieldNameIndex('objectid')
# get our selected feature from the provider, but we have to pass in an empty feature and the column index we want
sFeat = QgsFeature()
if self.provider.featureAtId(self.selectList[0], sFeat, True, [nIndx]):
# only if we have a 'NAME' column
if nIndx != -1:
# get the feature attributeMap
attMap = sFeat.attributeMap()
# clear old TextBrowser values
self.dlg.clearTextBrowser()
# now update the TextBrowser with attributeMap[nameColumnIndex]
# when we first retrieve the value of 'NAME' it comes as a QString so we have to cast it to a Python string
self.dlg.setTextBrowser( str( attMap[nIndx].toString() ))
# run method that performs all the real work
def run(self):
# set the current layer immediately if it exists, otherwise it will be set on user selection
self.cLayer = self.iface.mapCanvas().currentLayer()
if self.cLayer: self.provider = self.cLayer.dataProvider()
# make our clickTool the tool that we'll use for now
self.canvas.setMapTool(self.clickTool)
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result == 1:
# do something useful (delete the line containing pass and
# substitute with your code)
pass
Thanks in advance!