General scripting imporovements

I have been playing with scripting for last few weeks. And even with what already exposed to python you can do a lot of stuff :slight_smile: which makes me happy.

What I (as a plugin developer) would like to have in the future is ability to develop plugins without me requiring to know Krita source code.

In general on topic of things, that would be nice to see is following:

Connect to events
An ability to connect to certain events. Examples:

  • Selection added
  • Selection changed (moved, resized, edited, etc)
  • Layer added

There might be more useful events. I think other event can be brainstormed. These are the ones I would personally like to have.
Maybe Notifier class is a good candidate for that.

Make class representation for default dockers
We already have Palette class. It would be good to have a class for “Grid and Guides” for instance, to be able to manipulate grid and guides directly. Possibly other dockers can use class equivalent in Python API

Every action has a “completed” slot
The arguments of this slot contain all required settings for this action. For instance, the end of selection action would have a selection object as argument (or something like that). For the transform tool the values of translation, rotation, scale would be passed and so on.
This will add the flexibility to the plugin to trigger after user did something.

Disclaimer, I know that Krita uses QAction behind the scene and this request will probably require create your custom Action class.

Scripter window improvements
Some improvements (mainly usability) would be nice to see:

  1. Better text editor. I can make a separate list of things upon request. But in general it could see a better user experience in code writing.
  2. Better font for output panel. Sometimes for better debugging some tables can be rendered. It would be nice to have all characters constant size (including space) so that formatting with print can lead a good readable output. (I guess it can be solved just by setting another font [ship with krita to make sure])
  3. Do not close scripter with ‘ESC’ button. The scripter seems to be a popup window and can be closed with ESC key. However when debugging and working with tools that involve ESC key for cancel (such as transform tool) also leads to closing the window (which is annoying). At least let people configure this behavior in settings.

Make access to blending modes the same way as with actions and filters
I saw a TODO to make names as enumeration, maybe when it is done the list of blending modes also can be retrieved with a function.

Overall API unification
There are things that looks inconsistent. For instance Document.activeNode and View.selectedNodes produce a node or list of them. Though completely different classes to work with.

Script operation as atomic operation
Join set of commands from script to single operation to undo by single Ctrl+Z.
In other words if the script copy the node then rotates it then moves it than transforms it, user should cancel this operation with single undo operation. At least maybe let the plugin developer manually define that following set of operations will be treated as one. Maybe by calling functions like begin_as_one() and end_as_one().

Better debug output for forum support
Krita already has a window to show all the system information that can be included in bug report.

Maybe for scripting would be good to have something like that too. Some sort of a helper function to print everything the dev would need to know about document, krita, window, etc. to give proper support on scripting matter.

P.S. Again, these things are just from my point of view. Please treat it as a suggestion, rather then call to immediate action. I fully understand that devs have limited resources :slight_smile:

1 Like

Add View.setSelectedNodes(nodes) operation.

selecting nodes and active node aren’t really the same thing… active node is more like the primary node you are working on. Where as selecting node is for layer operations.

Well, if it helps:

from krita import *

qwin = Krita.instance().activeWindow().qwindow()
layerBox = qwin.findChild(QtWidgets.QDockWidget, "KisLayerBox")
layerList = layerBox.findChild(QTreeView,"listLayers")


model = layerList.model().sourceModel()


for i in range(model.rowCount()):
    idx = model.index(i,0)
    print (i, idx.data(2) )
    layerList.selectionModel().select(idx, QItemSelectionModel.Rows | QItemSelectionModel.Select)

print( Krita.instance().activeWindow().activeView().selectedNodes() )

Of course I am guessing this is what you meant by not needing to know the source?

Thanks for putting effort to lay down the code snippet.

Hm. What I need is to somehow make the layer selected after doing some changes (like adding other layers or groups).

The selection I need to trigger action, like Krita.instance().action("remove_layer).trigger()

For the example above it seems like I need to know the index of the layer. However, after I change the number of layers I have no idea what the index might be for the layer.

Searching by name is not an option as there might be other layers named the same.

Unless. Can I somehow determine the index of my layer (which I have a reference for) with this code example? The question might sound dump, I just do not know what types what line will return.

That is why making the layer active by reference would be pretty handy.

If you are in charge of handling removing/adding of layers, why would you not know how many layers were added/removed? You can get the index() of the layer in krita 5. Of course the index would change with the layers. In Krita 4 you would have to just get all the children and calculate the index yourself via parentNode().childNodes() and uniqueId() will tell you which node it is.