Tuesday 23 February 2016

qgis - How to call a method by BOTH a button AND a key shortcut



I have been trying to call a method by BOTH a key shortcut (as described here http://www.qgis.org/en/docs/pyqgis_developer_cookbook/snippets.html) and a button I created on the toolbar.


The button works but when I add the code for the shortcut, nothing happens.


def initGui(self):
# Code for the button
self.my_action = QAction(QIcon(":/path/to/the/icon.png"), u"toolName", self.iface.mainWindow())
self.my_action.triggered.connect(self.myFunction)
self.iface.addToolBarIcon(self.my_action)

# Code for the shortcut
self.iface.registerMainWindowAction(self.my_action, "Ctrl+1")

QObject.connect(self.my_action, SIGNAL("triggered()"),self.myFunction)

def unload(self):
# Unload the button
self.iface.removeToolBarIcon(self.my_action)

# Unload the shortcut
self.iface.unregisterMainWindowAction(self.my_action)

def myFunction(self):

doSomething

Can anybody tell me where (and how) to put the code explained in the link?


Thanks,


m.


EDIT#1


I don't know about my system (if other shortcuts work, I don't see why those set on my tools shouldn't) and as far as my code it is pretty straightforward: in the initGui method I set up the buttons (what I shared is a "place holder" for the real path of the icons. However, I can see them on both the toolbar and the settings form and everything works fine when clicking the buttons) add them to the toolbar; the unload method, unloads them (see the code above WITHOUT the redundant signal/slot connection as dakcarto pointed out in the comment); the run method sets up the environment (it points at the table -- I am editing a PostGIS table -- and starts an editing session + some tuning)


def run(self):
try:
# Reference to the layer

active_layer = self.iface.activeLayer()
# If vector type load a qml file from plugin dir
if active_layer.type() == QgsMapLayer.VectorLayer:
dirPlug = os.path.dirname(os.path.abspath(__file__))
active_layer.loadNamedStyle(dirPlug+"\\file.qml")
# Start editing session
active_layer.startEditing()
# Set CRS and zoom to extent
canvas = self.iface.mapCanvas()
canvas.mapRenderer().setProjectionsEnabled(True)

canvas.mapRenderer().setDestinationCrs(QgsCoordinateReferenceSystem(3857))
canvas.setExtent(active_layer.extent())
# Refresh
canvas.refresh()
self.iface.legendInterface().refreshLayerSymbology(active_layer)
except:
QMessageBox.warning(self.iface.mainWindow(),'WARNING','Please, make sure to select a valid shapefile in the TOC')

Then I have four buttons calling four identical methods that change values in three different fields of selected features (they differ from each other only for the values they are writing into the DB). Everything works fine when using buttons! I just can't connect a shortcut to them! One of these methods:


def oneOfThem(self):

try:
# Reference to the layer
active_layer = self.iface.activeLayer()
# selected features
sel = active_layer.selectedFeatures()
# datetime now
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M %S")
# username
user = getpass.getuser()
# if something is selected

if sel:
# Change values for selected features
for s in sel:
selID = s.id()
selUser = s.fieldNameIndex('user_lbl')
selRat = s.fieldNameIndex('rating')
selTime = s.fieldNameIndex('tile_done_')

active_layer.changeAttributeValue(selID, selUser, user)
active_layer.changeAttributeValue(selID, selRat, 1)

active_layer.changeAttributeValue(selID, selTime, now)

self.iface.messageBar().pushMessage("Info","Message.", QgsMessageBar.INFO, 3)
else:
self.iface.messageBar().pushMessage("WARNING","No features selected", QgsMessageBar.WARNING, 3)
except:
QMessageBox.warning(self.iface.mainWindow(),'WARNING','Please, make sure to select a valid shapefile in the TOC')

That's pretty much it! I didn't touch the _init_ method and I only added my code to the one coming from the Plugin Builder Plugin.


m.




Answer



You have a redundant signal/slot connection:


def initGui(self):
# Code for the button
self.my_action = QAction(QIcon(":/path/to/the/icon.png"), u"toolName", self.iface.mainWindow())
# Code for the shortcut
self.iface.registerMainWindowAction(self.my_action, "Ctrl+1")
self.my_action.triggered.connect(self.myFunction) # only need this new-style connection
self.iface.addToolBarIcon(self.my_action)


# duplicate old-style connection
# QObject.connect(self.my_action, SIGNAL("triggered()"),self.myFunction)

See if removing the duplicate helps. Also, try a different, unique key sequence in case there is a conflict with the "Ctrl+1" sequence.


Also, check Settings -> Configure shortcuts dialog to see if your registered QAction and key sequence are showing up.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...