# How to know which tool is currently in use

**URL:** <https://krita-artists.org/t/how-to-know-which-tool-is-currently-in-use/52421>\
**Category:** Plugins Development\
**Created:** [November 23, 2022, 12:50pm UTC](https://krita-artists.org/t/how-to-know-which-tool-is-currently-in-use/52421 "2022-11-23T12:50:23Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![Grum999](https://krita-artists.org/user_avatar/krita-artists.org/grum999/32/66488_2.png) [@Grum999](https://krita-artists.org/u/Grum999)\
**Post date:** [November 23, 2022, 1:00pm UTC](https://krita-artists.org/t/how-to-know-which-tool-is-currently-in-use/52421/2 "2022-11-23T13:00:40Z")

</div>

Hi

There’s no “easy” method for that

Here’s my module for that:

```auto
# -----------------------------------------------------------------------------
# PyKritaToolKit
# Copyright (C) 2019-2022 - Grum999
# -----------------------------------------------------------------------------
# SPDX-License-Identifier: GPL-3.0-or-later
#
# https://spdx.org/licenses/GPL-3.0-or-later.html
# -----------------------------------------------------------------------------
# A Krita plugin framework
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# The ekrita_tools module provides extended classes and method for Krita
#
# Main classes from this module
#
# - EKritaToolsId:
# Provides tools identifiers
#
# - EKritaToolsCategory
# Provides tools categories
#
# - EKritaTools:
# Provides methods for quick access to tools
#
# -----------------------------------------------------------------------------

from krita import *

from PyQt5.QtWidgets import (
        QWidget,
        QToolButton,
        QDockWidget
    )

from PyQt5.QtCore import (
        QObject,
        QSignalMapper,
        pyqtSignal as Signal
    )

# -----------------------------------------------------------------------------

class EInvalidValue(Exception):
    """An invalid value has been provided"""
    pass

class EKritaToolsId:
    """Tools Id

    Id is normally the same for QAction and QToolButton
    """
    SVG_SELECT = 'InteractionTool'
    SVG_TEXT = 'SvgTextTool'
    SVG_PATH = 'PathTool'
    SVG_CALLIGRAPHY = 'KarbonCalligraphyTool'

    TFM_TRANSFORM = 'KisToolTransform'
    TFM_MOVE = 'KritaTransform/KisToolMove'
    TFM_CROP = 'KisToolCrop'

    PAINT_BRUSH = 'KritaShape/KisToolBrush'
    PAINT_LINE = 'KritaShape/KisToolLine'
    PAINT_RECTANGLE = 'KritaShape/KisToolRectangle'
    PAINT_ELLIPSE = 'KritaShape/KisToolEllipse'
    PAINT_POLYGON = 'KisToolPolygon'
    PAINT_POLYLINE = 'KisToolPolyline'
    PAINT_PATH = 'KisToolPath'
    PAINT_PENCIL = 'KisToolPencil'
    PAINT_DYNAMIC_BRUSH = 'KritaShape/KisToolDyna'
    PAINT_MULTI_BRUSH = 'KritaShape/KisToolMultiBrush'

    FILL_GRADIENT = 'KritaFill/KisToolGradient'
    FILL_COLORSAMPLER = 'KritaSelected/KisToolColorSampler'
    FILL_COLORMASK = 'KritaShape/KisToolLazyBrush'
    FILL_SMARTPATCH = 'KritaShape/KisToolSmartPatch'
    FILL_BUCKET = 'KritaFill/KisToolFill'
    FILL_ENCLOSEFILL = 'KisToolEncloseAndFill'

    HELPER_ASSISTANT = 'KisAssistantTool'
    HELPER_MEASURE = 'KritaShape/KisToolMeasure'
    HELPER_REFIMG = 'ToolReferenceImages'

    SELECT_RECTANGLE = 'KisToolSelectRectangular'
    SELECT_ELLIPSE = 'KisToolSelectElliptical'
    SELECT_POLYGON = 'KisToolSelectPolygonal'
    SELECT_OUTLINE = 'KisToolSelectOutline'
    SELECT_CONTIGUOUS = 'KisToolSelectContiguous'
    SELECT_SIMILAR = 'KisToolSelectSimilar'
    SELECT_PATH = 'KisToolSelectPath'
    SELECT_MAGNETIC = 'KisToolSelectMagnetic'

    VIEW_ZOOM = 'ZoomTool'
    VIEW_PAN = 'PanTool'

class EKritaToolsCategory:
    """Categories to classify tools"""
    SVG = 'vector'
    TFM = 'transform'
    PAINT = 'paint'
    FILL = 'fill'
    HELPER = 'helper'
    SELECT = 'selection'
    VIEW = 'view'

class EKritaTools:
    """Tools definition"""

    class EKritaToolNotifier(QObject):
        toolChanged = Signal(str, bool)

    __TOOLS = {
        EKritaToolsId.SVG_SELECT: {
            'label': i18n('Select Shapes Tool'),
            'category': EKritaToolsCategory.SVG,
            'widget': None
            },
        EKritaToolsId.SVG_TEXT: {
            'label': i18n('Text Tool'),
            'category': EKritaToolsCategory.SVG,
            'widget': None
            },
        EKritaToolsId.SVG_PATH: {
            'label': i18n('Edit Shapes Tool'),
            'category': EKritaToolsCategory.SVG,
            'widget': None
            },
        EKritaToolsId.SVG_CALLIGRAPHY: {
            'label': i18n('Calligraphy'),
            'category': EKritaToolsCategory.SVG,
            'widget': None
            },

        EKritaToolsId.TFM_TRANSFORM: {
            'label': i18n('Transform a layer or a selection'),
            'category': EKritaToolsCategory.TFM,
            'widget': None
            },
        EKritaToolsId.TFM_MOVE: {
            'label': i18n('Move a layer'),
            'category': EKritaToolsCategory.TFM,
            'widget': None
            },
        EKritaToolsId.TFM_CROP: {
            'label': i18n('Crop the image to an area'),
            'category': EKritaToolsCategory.TFM,
            'widget': None
            },

        EKritaToolsId.PAINT_BRUSH: {
            'label': i18n("Freehand Brush Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_LINE: {
            'label': i18n("Line Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_RECTANGLE: {
            'label': i18n("Rectangle Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_ELLIPSE: {
            'label': i18n("Ellipse Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_POLYGON: {
            'label': i18n("Polygon Tool: Shift-mouseclick ends the polygon."),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_POLYLINE: {
            'label': i18n("Polyline Tool: Shift-mouseclick ends the polyline."),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_PATH: {
            'label': i18n("Bezier Curve Tool: Shift-mouseclick ends the curve."),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_PENCIL: {
            'label': i18n("Freehand Path Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_DYNAMIC_BRUSH: {
            'label': i18n("Dynamic Brush Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },
        EKritaToolsId.PAINT_MULTI_BRUSH: {
            'label': i18n("Multibrush Tool"),
            'category': EKritaToolsCategory.PAINT,
            'widget': None
            },

        EKritaToolsId.FILL_GRADIENT: {
            'label': i18n('Draw a gradient.'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },
        EKritaToolsId.FILL_COLORSAMPLER: {
            'label': i18n('Sample a colour from the image or current layer'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },
        EKritaToolsId.FILL_COLORMASK: {
            'label': i18n('Colourise Mask Tool'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },
        EKritaToolsId.FILL_SMARTPATCH: {
            'label': i18n('Smart Patch Tool'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },
        EKritaToolsId.FILL_BUCKET: {
            'label': i18n('Fill a contiguous area of colour with a colour, or fill a selection.'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },
        EKritaToolsId.FILL_ENCLOSEFILL: {
            'label': i18n('Enclose and Fill Tool'),
            'category': EKritaToolsCategory.FILL,
            'widget': None
            },

        EKritaToolsId.HELPER_ASSISTANT: {
            'label': i18n('Assistant Tool'),
            'category': EKritaToolsCategory.HELPER,
            'widget': None
            },
        EKritaToolsId.HELPER_MEASURE: {
            'label': i18n('Measure the distance between two points'),
            'category': EKritaToolsCategory.HELPER,
            'widget': None
            },
        EKritaToolsId.HELPER_REFIMG: {
            'label': i18n('Reference Images Tool'),
            'category': EKritaToolsCategory.HELPER,
            'widget': None
            },

        EKritaToolsId.SELECT_RECTANGLE: {
            'label': i18n('Rectangular Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_ELLIPSE: {
            'label': i18n('Elliptical Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_POLYGON: {
            'label': i18n('Polygonal Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_OUTLINE: {
            'label': i18n('Freehand Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_CONTIGUOUS: {
            'label': i18n('Contiguous Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_SIMILAR: {
            'label': i18n('Similar Colour Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_PATH: {
            'label': i18n('Bezier Curve Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },
        EKritaToolsId.SELECT_MAGNETIC: {
            'label': i18n('Magnetic Curve Selection Tool'),
            'category': EKritaToolsCategory.SELECT,
            'widget': None
            },

        EKritaToolsId.VIEW_ZOOM: {
            'label': i18n('Zoom Tool'),
            'category': EKritaToolsCategory.VIEW,
            'widget': None
            },
        EKritaToolsId.VIEW_PAN: {
            'label': i18n('Pan Tool'),
            'category': EKritaToolsCategory.VIEW,
            'widget': None
            }
        }

    __notifier = None
    __toolbox = None
    __signalMapper = QSignalMapper()

    notifier = EKritaToolNotifier()

    @staticmethod
    def init():
        """Initialise static class"""
        def __toolChanged(id):
            """tool has been changed, emit signal"""
            EKritaTools.notifier.toolChanged.emit(id, EKritaTools.__TOOLS[id]['widget'].isChecked())

        def __windowCreated():
            """Executed when a Krita window is created"""
            if EKritaTools.__toolbox is None:

                EKritaTools.__toolbox = Krita.instance().activeWindow().qwindow().findChild(QDockWidget, 'ToolBox')

                EKritaTools.__signalMapper.mapped[str].connect(__toolChanged)

                for id in list(EKritaTools.__TOOLS.keys()):
                    toolButton = EKritaTools.__toolbox.findChild(QToolButton, id)
                    if toolButton:
                        EKritaTools.__TOOLS[id]['widget'] = toolButton
                        toolButton.toggled.connect(EKritaTools.__signalMapper.map)
                        EKritaTools.__signalMapper.setMapping(toolButton, id)

        if EKritaTools.__toolbox is None:
            EKritaTools.toolChanged = Signal(str, bool)
            EKritaTools.__notifier = Krita.instance().notifier()

            EKritaTools.__notifier.setActive(True)
            EKritaTools.__notifier.windowCreated.connect(__windowCreated)

    @staticmethod
    def list(filter=None):
        """Return list of available tools Id

        If given, `filter` is EKritaToolsCategory value or a list of EKritaToolsCategory values
        In this case, only tools matching given category are returned

        if given `filter` is not valid, return empty list
        """
        if filter is None:
            return list(EKritaTools.__TOOLS.keys())
        else:
            if isinstance(filter, str):
                # convert to list
                filter = [filter]
            if isinstance(filter, (list, tuple)):
                return [id for id in list(EKritaTools.__TOOLS.keys()) if EKritaTools.__TOOLS[id]['category'] in filter]
        return []

    @staticmethod
    def get(id):
        """Return tool definition for given id

        returned definition is a dictionnary with following keys:
            'label': <str>, translated label for tool
            'category': <str>, group for tool
            'widget': <QWidget>, widget for tool
        """
        try:
            return EKritaTools.__TOOLS[id]
        except Exception:
            raise EInvalidValue("Given `id` is not valid")

    @staticmethod
    def name(id):
        """Return tool label definition for given id"""
        try:
            return EKritaTools.__TOOLS[id]['label']
        except Exception:
            raise EInvalidValue("Given `id` is not valid")

    @staticmethod
    def category(id):
        """Return tool category definition for given id"""
        try:
            return EKritaTools.__TOOLS[id]['category']
        except Exception:
            raise EInvalidValue("Given `id` is not valid")

    @staticmethod
    def current(filter=None):
        """return id of current tool

        If given, `filter` is EKritaToolsCategory value or a list of EKritaToolsCategory values
        In this case, id is returned for tools for which category is matching given filter; Otherwise return None

        if given `filter` is not valid, return None
        """
        for id in EKritaTools.list(filter):
            toolButton = EKritaTools.__TOOLS[id]['widget']
            if toolButton and toolButton.isChecked():
                return id
        return None

    @staticmethod
    def setCurrent(id):
        """Set current paint tool from given `id`"""
        if id in EKritaTools.__TOOLS and id != EKritaTools.current():
            Krita.instance().action(id).trigger()

# -------------------------------------------------------------------------------------
# initialise module
EKritaTools.init()

```

Basically for your need, once module is imported, just use `EKritaTools.current()`

Grum999

---

_[View the full topic](https://krita-artists.org/t/how-to-know-which-tool-is-currently-in-use/52421)._
