Would it be possible to call other’s docker method/button from my extension/docker?
Context:
I’m making some kind of palette generator and I’d like to make a button to add at the same time more than 1 color to the ‘PaletteDocker’ docker in Krita:
The + button may contain the logic I need.
I can get the docker, but not sure what to do next:
app = Krita.instance()
w = app.activeWindow()
def get_palette_docker():
for d in w.dockers():
if d.objectName() == 'PaletteDocker':
return d
pd = get_palette_docker()
# Not sure what to do next.
# type(pd) is QDockWidget, so when calling
# print(dir(pd)) im getting QDockWidget methods so I don't
# know how to 'explore' the methods from the palette that
# I could call for my purposse
(Probably I shouldn’t call others widgets functions (?) (since well, if they change, my extension will break). But since that palette is native from Krita I would preffer to add my colours there instead of creating my own palette system).
The general way to go about this is to first check the API, if not in the API, check the Actions. If it isn’t there, then you access the PyQt. I suggest using the python developer tools to find the item you want in Inspector, then click on the Event/Signal Viewer, it will show you all the signals and events. By playing play and doing an action, you can see what actions and events are triggered and use them
In your specific case, be aware that PaletteView exists, double check first if that meets your needs. If not, then see the signals
Thank you so much for the help, to be honest I appreciate the guidance since sometimes I feel that I’m doing things in a way that feels non-propper or “hacky”.
Also, I found your DevTools plugin to be (again) super helpful. I was able to examine the palette-docker and found one of its methods that was useful for my needs (slotAddColor()).
But since you said the API I took a look and found a better method in Palette (addEntry()) (“Better” since I expet it to don’t trigger an UI dialog as slotAddColor())
*(This is an example of what I mean that sometimes I feel I do things in a non-propper way. I’t trying to get the active Palette. And for knowing which one is active I’m using… a label in the docker )
from krita import *
from PyQt5.QtWidgets import QLabel
app = Krita.instance()
def get_palette_docker():
active_window = app.activeWindow()
for d in active_window.dockers():
if d.objectName() == 'PaletteDocker':
return d
def get_active_palette():
palette_docker = get_palette_docker()
palettes = app.resources('palette')
# This feels ""hacky""; accessing the active palette by a label in the UI:
# active_palette_key = palette_docker.lblPaletteName.text() # `lblPaletteName` is the label in the palette docker that shows the active palette
label = palette_docker.findChild(QLabel, "lblPaletteName")
active_palette_key:str = label.text() # `lblPaletteName` is the label in the palette docker that shows the active palette
# When a palette has been modified, it starts with "* "
if active_palette_key.startswith("* "):
active_palette_key = active_palette_key.replace("* ", "")
return Palette(palettes[active_palette_key])
active_palette = get_active_palette()
print(f"{active_palette.colorsCountTotal() = }")
(Maybe I shouldn’t worry, if it works, it works. But feels bad xD)
Do you know where/when is the best place/moment for loading & saving my plugin’s data?
I searched in the API, and I’ve only found the Window’s signal windowClosed(), that maybe could be an option.
Is it? Or there is a better option (maybe some kind of signal krita sends when is about to close)?
It’s definitely a hack anytime your script has to search through the UI for something, yes. But Krita’s API is currently pretty limited compared to all the things the program can do, so there is no proper way to do a lot of things through script.
Re: saving/loading data: For settings, you might load them when you use them and save them when they are modified. For other kinds of data there’s the Notifier which has imageClosed and applicationClosing signals.
Is it possible to trigger a color picker and connect it to a signal to know when a color is picked (so I can later use that picked color)?
Context: I’m using a button to trigger a QColorDialog. In the dialog there is already a color picker, but I’m making some kind of shortcuts in the button (like Alt+Click selects FG color, Right-Click, the BG color, etc. And I would like to add an option to directly trigger the color picker). I’ve searched in Krita and Qt’s API but I found nothing.
I have a few buttons that I’d like to be enable/disable depending on the selected/active layer (and also to display the layer name in button’s text, etc).
But the problem with paintEvent() is that is only called/updated when the mouse is over (so its weird for the user to go to press a button and then changing it to disable when it hoovers it).
Is there maybe a signal that is called when the Krita’s UI is being drawn? Or maybe to know when the active layer has changed?
What kind of button? Where exactly are you struggling, in telling when a layer changes state or the call to disable and enable the buttons?
Because most buttons should respond to setEnabled(), it’s inherited from QWidget. For some elements the disabled state isn’t obvious; They’ll stop changing under hover but won’t become grayed out, you have to set opacity manually.
What kind of button? Where exactly are you struggling, in telling when a layer changes state or the call to disable and enable the buttons?
Is a QPushButton. I’m struggling in finding when a new layer is selected/active, so I can properly determine if the button has to be disabled and do some other changes (like changing the button’s text when a new layer is selected).
setEnabled() is working btw, my problem is about knowing when the active layer has changed (or when the Krita’s UI has changed (like when we select a different layer)) so I can make my changes in my Docker’s buttons.