This topic is a place to freely post little scripts that can be used in Krita.
Do you have a short script that you use on a regular basis, or a script that you wrote on a whim but found it useless?
What may be boring code to you may be a coding tip to someone else. Please post your scripts here that aren’t good enough to be finished as a plugin, and as Krita Scripting’s sample code accumulates, the result will be an important resource. Scripts that can be pasted into the scripter and executed are preferred, but those that do not are acceptable.
Topic Policy
Scripts do not have to be advanced
Scripts can be useful or not.
You do not have to maintain your own scripts. You are not obligated to answer questions or requests from anyone.
A script can be enclosed by writing three grave accents ``` above and below its text.
from krita import (
Krita,)
from PyQt5.QtWidgets import (
QApplication,
QDockWidget,
QToolButton)
def call_liquify():
app = Krita.instance()
qwin = app.activeWindow().qwindow()
KisToolTransform = app.action(“KisToolTransform”)
KisToolTransform.trigger()
# give krita some time to process tool change…
QApplication.processEvents()
# now, KisToolTransform should be fully initilized.
liquifyButton = qwin.findChild(QToolButton, “liquifyButton”)
liquifyButton.click()
call_liquify()
I have collected all the scripts I have seen (from github and KA forums). Although I marked them with Chinese notes, you can know their usage from the original links: 脚本 (yuque.com)
Krita erases the canvas when the (‘fill_selection_foreground_color’) action is performed if the current pen is in erase mode. However, switching pens to perform a fill can be tedious. This script allows you to always fill with foreground color no matter what setting you have your pen set to.
What a great idea! I often fill with “erasing” accidentally, which disorientates me when it happens. For a total script noob like me, where should I paste this script to make it auto-loading whenever I start a new Krita session?
The easiest way is to save this code as a text file and register it in ten scripts. The script will then be able to be executed by actions or action shortcuts.
To attach it to Krita as an extension, I would need to create a plugin file, but that is outside the scope of this “feel free to leave code” topic for me to do.
Oops, correction.
When saving code, use “.py” instead of “.txt” extension.
For example, if you name the file “fillColorAbs.py” and save it, ten scripts will be able to load it.
But it works without Python installed? I’m also just a beginner so I don’t know.
Krita’s “Activate Previous Layer” action cannot select a layer over two or more “steps” in a group. The layer selection is stopped in the middle of the layer group hierarchy.
This script avoids that and always moves to the layer below in the layer docker.
I feel like it could be cleaner code, but this topic also allows for dirty code…
from krita import Krita
from PyQt5.QtCore import (
Qt,
QPoint,
QPointF,
QEvent)
from PyQt5.QtGui import (
QMouseEvent,
QCursor)
from PyQt5.QtWidgets import (
QWidget,
QApplication)
def find_current_canvas():
application = Krita.instance()
q_window = application.activeWindow().qwindow()
q_stacked_widget = q_window.centralWidget()
q_mdi_area = q_stacked_widget.currentWidget()
q_mdi_sub_window = q_mdi_area.currentSubWindow()
view = q_mdi_sub_window.widget()
for c in view.children():
if c.metaObject().className() == 'KisCanvasController':
viewport = c.viewport()
canvas = viewport.findChild(QWidget)
return canvas
def click_canvas(global_pos=None):
canvas = find_current_canvas()
if global_pos is None:
global_pos = QCursor.pos()# cursor position
global_posF = QPointF(global_pos)
posF = QPointF(canvas.mapFromGlobal(global_pos))
else:
global_pos = QPoint(global_pos)
global_posF = QPointF(global_pos)
posF = QPointF(canvas.mapFromGlobal(global_pos))
button = Qt.LeftButton
buttons = Qt.LeftButton
key_state = Qt.NoModifier
mouse_press = QMouseEvent(
QEvent.MouseButtonPress,
posF,
button,
buttons,
key_state)
mouse_release = QMouseEvent(
QEvent.MouseButtonRelease,
posF,
button,
buttons,
key_state)
if not canvas.isActiveWindow():
canvas.activateWindow()
QApplication.sendEvent(canvas, mouse_press)
QApplication.sendEvent(canvas, mouse_release)
click_canvas()
This is a simplified version of the one taught in this topic.
It can be used to force tools that require manual clicking, such as continuous selection or layer selection, to work programmatically, but it will not be useful in many situations.
Note that if you register this script to a shortcut that includes the Shift key, for example, the result will be a Shift+click situation.
To create new layer under the current layer instead of on top of current layer
from krita import *
def getNextSibling(node):
previousNode=None
for foundNode in node.parentNode().childNodes():
if foundNode==node:
return previousNode
previousNode=foundNode
return previousNode
doc=Krita.instance().activeDocument()
if doc:
currentNode=doc.activeNode()
if currentNode:
newNode=doc.createNode(“New paint layer”, “paintlayer”) >currentNode.parentNode().addChildNode(newNode, getNextSibling(currentNode))
import time
application = Krita.instance()
for i in range(16):
application.action('duplicatelayer').trigger()
time.sleep(0.1)
application.action('merge_layer').trigger()
This script duplicates the current layer and merges it back again up to 16 times, the square root of 256, the maximum value of alfa, enough to make opaque even a single pixel of 1% of transparency >:)
Is it possible to change the Distance of the Weighted Brush smoothing? Not only that, but check to see what value it has and change to something else accordingly? Each time the script is executed: If X, then change it to Y. If Y, then change it to X.
Script to enlarge or shrink the current selection mask.
def selectionPM(n):
application = Krita.instance()
activeDoc = application.activeDocument()
s = activeDoc.selection()
if s == None:
pass
elif n > 0:
s.grow(n, n)
application.action('invert_selection').trigger()
application.action('invert_selection').trigger()
else:
s.shrink(abs(n), abs(n), True)
application.action('invert_selection').trigger()
application.action('invert_selection').trigger()
selectionPM(-2)# input number to ( )
Entering a positive number in the parentheses of “selectionPM()” will enlarge the selection, and entering a negative number will shrink it.
For example, typing “selectionPM(5)” will enlarge the selection by 5px.