# Falkon Python Tutorial - 3. Adding a button to the toolbar In this chapter will be shown how to add Simple button to the toolbar. The button has to be added to every window. The button has to be added to new windows and removed when the window is closing. ## Fill metadata It feels like a paperwork but it has to be done. *metadata.desktop* ``` [Desktop Entry] Name=Falkon Python Tutorial 3 Comment=Adding a button to the toolbar Icon= Type=Service X-Falkon-Type=Extension/Python X-Falkon-Author=Juraj Oravec X-Falkon-Email=sgd.orava@gmail.com X-Falkon-Version=1.0.0 X-Falkon-Settings=false ``` ## Create button *TutorialButton.py* ```python import Falkon class TutorialButton(Falkon.AbstractButtonInterface): def __init__(self): super().__init__() self.number = 0 self.setTitle("Tutorial 3") self.setToolTip("Increment the number") self.setBadgeText(str()) self.clicked.connect(self.onClicked) def id(self): return "falkon-python-tutorial-3-button" def name(self): return "Falkon Python Tutorial 3 Button" def onClicked(self, controller): self.number += 1 self.setBadgeText(str(self.number)) ``` The button class has to inherit from `Falkon.AbstractButtonInterface`[1] ### Falkon.AbstractButtonInterface The interface class for Falkon buttons. #### id() This id will be used by Falkon when you add the button to toolbar to determinate its place in the toolbar. #### name() The name which will be displayed in "Configure toolbar" dialog. #### setTitle() I did not find a sensible use for this function in the Falkons code yet. #### setToolTip() The buttons tooltip which will be displayed when you hover with mouse over the button. #### setBadgeText() The text in a form of a badge over the button. Used by **AdBlock** plugin to show how many item it blocked. **Note:** When I set the badgeText in \__init__() it did not show in UI. Maybe bug, maybe intentional behaviour, ask the Falkon author. #### clicked event Emitted when the mouse click on the button. In this example this signal is connected to `onClicked()` method #### onClicked() The variable number is increased and its value is shown in the button badge. ## Plugin module *\__init__.py* ```python import Falkon from PySide2 import QtCore from Tutorial3.TutorialButton import TutorialButton class Tutorial3_Plugin(Falkon.PluginInterface, QtCore.QObject): def init(self, state, settingsPath): self.buttons = {} plugins = Falkon.MainApplication.instance().plugins() plugins.mainWindowCreated.connect(self.mainWindowCreated) plugins.mainWindowDeleted.connect(self.mainWindowDeleted) if state == Falkon.PluginInterface.LateInitState: for window in Falkon.MainApplication.instance().windows(): self.mainWindowCreated(window) def unload(self): for window in Falkon.MainApplication.instance().windows(): self.mainWindowDeleted(window) def testPlugin(self): return True def mainWindowCreated(self, window): b = TutorialButton() window.navigationBar().addToolButton(b) self.buttons[window] = b def mainWindowDeleted(self, window): if window not in self.buttons: return b = self.buttons[window] window.navigationBar().removeToolButton(b) del self.buttons[window] Falkon.registerPlugin(Tutorial3_Plugin()) ``` To add a button to the Falkon interface we need to create new button for each window and store it somewhere. To add button to each window we create `mainWindowCreated()` and `mainWindowDeleted()` methods. ```python def mainWindowCreated(self, window): b = TutorialButton() # Create an instance of the button window.navigationBar().addToolButton(b) # Add button to toolbar self.buttons[window] = b # store the button def mainWindowDeleted(self, window): if window not in self.buttons: # Check if the button exist for selected window return b = self.buttons[window] window.navigationBar().removeToolButton(b) # remove the button from toolbar del self.buttons[window] ``` When the methods are ready we connect them to `mainWindowCreated` and `mainWindowDeleted` event. ```python plugins = Falkon.MainApplication.instance().plugins() plugins.mainWindowCreated.connect(self.mainWindowCreated) plugins.mainWindowDeleted.connect(self.mainWindowDeleted) ``` Variable `plugins` is an instance of [PluginProxy](https://github.com/KDE/falkon/blob/master/src/lib/plugins/pluginproxy.h). In case the extension is enabled when Falkon is already running we need to manually call `mainWindowCreated` method for each window. ```python if state == Falkon.PluginInterface.LateInitState: for window in Falkon.MainApplication.instance().windows(): # Get list of currently open windows self.mainWindowCreated(window) ``` ## Add button to statusbar At the moment of writing this tutorial Falkon does not have any kind of configuration dialog to arrange buttons. Buttons in statusbar are shown on 'first come first served' basis. To add button to statusbar only two lines are needed. ### Update mainWindowCreated() The line which needs to be added: ```python window.statusBar().addButton(b) ``` ### Update mainWindowDeleted() The line which needs to be added: ```python window.statusBar().removeButton(b) ``` ### The result ```python def mainWindowCreated(self, window): b = TutorialButton() window.navigationBar().addToolButton(b) window.statusBar().addButton(b) # For statusbar self.buttons[window] = b def mainWindowDeleted(self, window): if window not in self.buttons: return b = self.buttons[window] window.navigationBar().removeToolButton(b) window.statusBar().removeButton(b) # For statusbar del self.buttons[window] ``` It is simple, right ? [1]: https://github.com/KDE/falkon/blob/master/src/lib/tools/abstractbuttoninterface.h