The script I’m trying to make puts an outline behind the current layer and places both the outline layer and original layer in a group. I’ve gotten most of it working how I want, the issue I’ve run into is that after the script finishes, the active layer is the (clone of) the original layer I was working on, and I want it to be the group that the original layer and outline layer have been placed into.
Using the setActiveNode command seems to do nothing.
I’ve attempted a fix proposed in other similar threads using this sleep function:
but it seems to have no effect; I’ve tried up to 5000. I’ve also sprinkled in waitForDone all over the place to no avail either. I’m new to scripting so it’s a bit noodley, but this is what I have:
from krita import *
from PyQt5.QtGui import (QColor,)
inst = Krita.instance()
doc = inst.activeDocument()
toOutline = doc.activeNode()
inst.action('selectopaque').trigger()
inst.action('growselection').trigger()
doc.waitForDone()
i = InfoObject()
i.setProperty("color", QColor(255, 255, 255))
outline = doc.createFillLayer("Outline", "color", i, doc.selection())
group = doc.createGroupLayer("01")
toOutline.parentNode().addChildNode(group, toOutline)
nodes = [outline, toOutline.clone()]
for node in nodes:
group.addChildNode(node, None)
toOutline.remove()
inst.action('deselect').trigger()
doc.waitForDone()
doc.setActiveNode(group)
You can just add the group last. Any new layer added would get focus so moving toOutline.parentNode().addChildNode(group, toOutline) down after the addChildNode loop would achieve what you want without the setActiveNode. In general, it is best to build all your layer structures first, then add the whole structure at once rather than adding them one by one
If you realy like to edit current node and selected nodes following script can be used. Have fun.
from krita import Krita
from PyQt5.QtCore import Qt, QModelIndex, QItemSelectionModel
from PyQt5.QtWidgets import QTreeView
def get_layer_model():
app = Krita.instance()
kis_layer_box = next((d for d in app.dockers() if d.objectName() == 'KisLayerBox'), None)
view = kis_layer_box.findChild(QTreeView, 'listLayers')
return view.model(), view.selectionModel()
def node_to_index(node, model):
path = list()
while node and (node.index() >= 0):
path.insert(0, node.index())
node = node.parentNode()
index = QModelIndex()
for i in path:
last_row = model.rowCount(index) - 1
index = model.index(last_row - i, 0, index)
return index
def index_to_node(index, document):
if not index.isValid():
raise RuntimeError('Invalid index')
model = index.model()
path = list()
while index.isValid():
last_row = model.rowCount(index.parent()) - 1
path.insert(0, last_row - index.row())
index = index.parent()
node = None
children = document.topLevelNodes()
for i in path:
node = children[i]
children = node.childNodes()
return node
# testing:
# following script will change target_node to be current node,
# also selection is kept and extended to current node.
#
# before running:
# create new document, and add some nodes and node groups
# add one node named target_node
app = Krita.instance()
doc = app.activeDocument()
target_node = doc.nodeByName('target_node')
model, s_model = get_layer_model()
index = node_to_index(target_node, model)
s_model.setCurrentIndex(index, QItemSelectionModel.Select) # or QItemSelectionModel.SelectCurrent
That works with some finagling, thank you! I’m still wrapping my head around the idea of manipulating layers that aren’t added to the layer hierarchy yet