Com crear un connector en Python per al Krita¶
És possible que tingueu alguns bons scripts escrits a l'executor Scripter de Python, però potser voleu fer més amb ell i executar-lo automàticament. Embolcallar el vostre script en un connector pot donar-vos molta més flexibilitat i executar scripts des de l'editor Scripter.
Bé, fins i tot si coneixeu el Python realment bé, hi ha alguns petits detalls perquè el Krita reconegui un connector en Python. De manera que aquesta pàgina us donarà una descripció general sobre com crear els diferents tipus de scripts en Python únics al Krita.
Aquestes mini guies d'aprenentatge estan escrites per persones amb un coneixement bàsic de Python, i de manera que fomenten l'experimentació en lloc de copiar i enganxar el codi, així que llegiu el text detingudament.
Aconseguir que el Krita reconegui el vostre connector¶
Un script al Krita té dos components: directori de l'script (conté els fitxers en Python per al vostre script) i un fitxer «.desktop» que el Krita fa servir per a carregar i enregistrar el vostre script. Perquè el Krita carregui el vostre script, tots dos hauran d'estar al subdirectori pykrita
de la vostra carpeta de recursos del Krita (per als camins segons el sistema operatiu, vegeu Gestionar els recursos). Per a trobar la vostra carpeta de recursos, inicieu el Krita i feu clic a l'element de menú « ». Això obrirà un diàleg. Feu clic al botó Obre la carpeta de recursos. Aquest hauria d'obrir un gestor de fitxers en el vostre sistema amb la carpeta de recursos del Krita. Vegeu els documents de l'API sota «Auto starting scripts». Si no hi ha una subcarpeta pykrita
al directori de recursos del Krita, utilitzeu el vostre gestor de fitxers per a crear-la.
Els scripts s'identifiquen per un fitxer que acaba amb una extensió .desktop
, el qual conté informació sobre l'script en si.
Per tant, per a cada connector haureu de crear una carpeta i un fitxer d'escriptori.
El fitxer d'escriptori s'hauria d'assemblar al següent:
[Desktop Entry]
Type=Service
ServiceTypes=Krita/PythonPlugin
X-KDE-Library=myplugin
X-Python-2-Compatible=false
X-Krita-Manual=myPluginManual.html
Name=My Own Plugin
Comment=Our very own plugin.
- Type
Aquest sempre haurà de ser «service» (servei).
- ServiceTypes
Aquest sempre haurà de ser
Krita/PythonPlugin
per als connectors en Python.- X-KDE-Library
Aquest haurà de ser el nom de la carpeta del connector que acabeu de crear.
- X-Python-2-Compatible
Quan és compatible amb el Python 2. Si el Krita es va construir amb el Python 2 en lloc del 3 (
-DENABLE_PYTHON_2=ON
a la configuració del «cmake»), llavors aquest connector no apareixerà a la llista.- X-Krita-Manual
Un valor opcional que apuntarà a l'element manual. Això es mostra al gestor de connectors en Python. Si és un fitxer HTML, es mostrarà com a text enriquit, en cas contrari, es mostrarà com a text sense format.
- Name
El nom que es mostrarà al gestor de connectors en Python.
- Comment
La descripció que es mostrarà al gestor de connectors en Python.
Els connectors en Python del Krita hauran de ser mòduls de Python, així que assegureu-vos que hi hagi un script __init__.py
que contingui quelcom com...
from .myplugin import *
On «.myplugin» és el nom del fitxer principal del vostre connector. Si reinicieu el Krita, ara hauria de mostrar-lo a la configuració del Gestor de connectors en Python, però estarà en gris, perquè no hi ha el «myplugin.py». Si passeu per sobre dels connectors inhabilitats, veureu l'error.
Nota
Cal que habiliteu explícitament el vostre connector. Aneu al menú Arranjament, obriu el diàleg Configuració del Krita i aneu a la pàgina Gestor de connectors en Python i habiliteu el vostre connector.
Resum¶
En resum, si voleu crear un script anomenat myplugin
:
- en el directori
resources/pykrita
del Krita creareu una carpeta anomenada
myplugin
un fitxer anomenat
myplugin.desktop
- en el directori
- a la carpeta
myplugin
creareu un fitxer anomenat
__init__.py
un fitxer anomenat
myplugin.py
- a la carpeta
al fitxer
__init__.py
introduïu aquest codi:
from .myplugin import *
al fitxer d'escriptori introduïu aquest codi:
[Desktop Entry] Type=Service ServiceTypes=Krita/PythonPlugin X-KDE-Library=myplugin X-Python-2-Compatible=false Name=My Own Plugin Comment=Our very own plugin.
escriviu el vostre script al fitxer
myplugin/myplugin.py
.
Crear una extensió¶
Les extensions són scripts en Python relativament senzills que s'executen durant l'inici del Krita. Es fan estenent la classe «Extension», i l'extensió més troncal es veu així:
from krita import *
class MyExtension(Extension):
def __init__(self, parent):
# Això està inicialitzant el pare, sempre important quan és una subclasse.
super().__init__(parent)
def setup(self):
pass
def createActions(self, window):
pass
# I s'afegeix l'extensió a la llista d'extensions del Krita:
Krita.instance().addExtension(MyExtension(Krita.instance()))
Aquest codi, per descomptat, no fa res. Normalment, a «createActions» afegim accions al Krita, de manera que podrem accedir al nostre script des del menú Eines.
Primer, crearem una acció. Podem fer-ho amb facilitat amb Window.createAction(). El Krita cridarà a «createActions» per a cada finestra que es creï i passarà l'objecte a la finestra correcte que hem d'utilitzar.
Així que...
def createActions(self, window):
action = window.createAction("myAction", "El meu script", "tools/scripts")
- «myAction»
Això haurà de ser substituït amb un ID únic que el Krita utilitzarà per a trobar l'acció.
- «El meu script»
Això és el que serà visible en el El menú Eines.
Si ara reinicieu el Krita, tindreu una acció anomenada «El meu script». Encara no fa res, perquè no l'hem connectat amb un script.
Llavors, creem un senzill script d'exportació de documents. Afegim el següent a la classe «Extension», assegureu-vos que estigui a sobre d'on afegiu l'extensió al Krita:
def exportDocument(self):
# Obtenir el document:
doc = Krita.instance().activeDocument()
# El desament d'un document inexistent provoca errors, de manera que comproveu primer el document.
if doc is not None:
# Això crida el diàleg per a desar. El diàleg de desar retorna una tupla.
fileName = QFileDialog.getSaveFileName()[0]
# I exporta el document a la ubicació de «FileName».
# «InfoObject» és un diccionari amb opcions específiques per a l'exportació, però quan es crea un buit, el Krita utilitzarà els valors predeterminats per a l'exportació.
doc.exportImage(fileName, InfoObject())
I afegiu la importació per a «QFileDialog» a sobre amb les importacions:
from krita import *
from PyQt5.QtWidgets import QFileDialog
Després, per a connectar l'acció amb el nou document d'exportació:
def createActions(self, window):
action = window.createAction("myAction", "El meu script")
action.triggered.connect(self.exportDocument)
Aquest és un exemple d'una connexió de senyal/ranura, el qual utilitzen molt les aplicacions Qt com el Krita. Repassarem una mica més endavant com crear els nostres propis senyals i ranures.
Reinicieu el Krita i la vostra nova acció hauria d'exportar el document.
Crear dreceres de teclat configurables¶
Ara, la vostra nova acció no apareix a «
».Per diverses raons, el Krita només afegeix accions al Configuració de les dreceres quan estan presents en un fitxer .action
. El fitxer d'acció perquè la nostra acció s'afegeixi a les dreceres haurà de tenir aquest aspecte:
<?xml version="1.0" encoding="UTF-8"?>
<ActionCollection version="2" name="Scripts">
<Actions category="Scripts">
<text>Els meus scripts</text>
<Action name="myAction">
<icon></icon>
<text>El meu script</text>
<whatsThis></whatsThis>
<toolTip></toolTip>
<iconText></iconText>
<activationFlags>10000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut>ctrl+alt+shift+p</shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
</Actions>
</ActionCollection>
- <text>Els meus scripts</text>
Això crearà una subcategoria anomenada «Els meus scripts» sota els scripts per a afegir-la a les vostres dreceres.
- name
Aquest haurà de ser l'ID exclusiu que vàreu crear per a la vostra acció en crear-lo a l'ajust de l'extensió.
- icon
El nom d'una possible icona. Aquesta només es mostrarà al Plasma del KDE, perquè els usuaris del Gnome i de Windows es van queixar que es veien lletges.
- text
El text que es mostrarà a l'editor de les dreceres.
- whatsThis
El text que es mostrarà quan una aplicació Qt cridi específicament a «Què és això», la qual és una acció d'ajuda.
- toolTip
El consell de l'eina, apareixerà en passar per sobre.
- iconText
El text que es mostrarà quan es mostri en una barra d'eines. Així, per exemple, «Resize Image to New Size» (Redimensiona la imatge a una mida nova) es podria escurçar a «Resize Image» (Redimensiona la imatge) per a estalviar espai, així que el posaríem aquí.
- activationFlags
Això determina quan una acció està o no inhabilitada.
- activationConditions
Això determina les condicions d'activació (p. ex., activar només quan la selecció sigui editable). Vegeu el codi per a exemples.
- shortcut
Drecera predeterminada.
- isCheckable
Quan es tracta o no d'una casella de selecció.
- statusTip
El consell d'estat que es mostra en una barra d'estat.
Deseu aquest fitxer com a myplugin.action
on myplugin
serà el nom del vostre connector. Ara s'haurà de desar el fitxer d'acció, no a la carpeta de recursos «pykrita», sinó en una carpeta de recursos anomenada «actions». (De manera que a share/pykrita
és on van els connectors en Python i els fitxers, i a share/actions
és on van els fitxers d'acció). Torneu a iniciar el Krita. Ara hauria d'aparèixer la drecera a la llista d'accions amb drecera.
Crear un acoblador¶
Crear un acoblador personalitzat és molt semblant a crear una extensió. Els acobladors són, en certa manera, una mica més fàcils, però també requereixen un ús major dels ginys. Aquest és el codi troncal de l'acoblador:
from PyQt5.QtWidgets import *
from krita import *
class MyDocker(DockWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("El meu acoblador")
def canvasChanged(self, canvas):
pass
Krita.instance().addDockWidgetFactory(DockWidgetFactory("myDocker", DockWidgetFactoryBase.DockRight, MyDocker))
El títol de la finestra és com apareixerà a la llista d'acobladors en el Krita. La «canvasChanged» sempre haurà d'estar present, però no heu de fer res amb això, de manera que només «pass».
Per a l'«addDockWidgetFactory»...
- «myDocker»
Substituïu això amb un ID únic per al vostre acoblador que utilitza el Krita per a fer un seguiment.
- DockWidgetFactoryBase.DockRight
La ubicació. Aquesta pot ser
DockTornOff
,DockTop
,DockBottom
,DockRight
,DockLeft
oDockMinimized
- MyDocker
Substituïu això amb el nom de la classe de l'acoblador que voleu afegir.
De manera que, si afegim la nostra funció d'exportació de documents que hem creat a la secció extensió a aquest codi de l'acoblador. Com permetem que l'usuari l'activi? Primer, haurem de crear codi IGU per a les Qt: Afegim un botó!
De manera predeterminada, el Krita utilitza el PyQt, però la seva documentació és força dolenta, principalment perquè la documentació de les Qt és realment bona, i sovint trobareu que la documentació de PyQt d'una classe, diu, el QWidget és com una còpia estranya de la documentació de les Qt per a aquesta classe.
De totes maneres, el primer que hem de fer és crear un QWidget
, no és molt complicat, a sota de setWindowTitle
, afegiu:
mainWidget = QWidget(self)
self.setWidget(mainWidget)
A continuació, crearem un botó:
buttonExportDocument = QPushButton("Export Document", mainWidget)
Ara, per a connectar el botó amb la nostra funció, haurem de veure els senyals a la documentació. El QPushButton no té senyals únics propis, però si diu que hereta 4 senyals des de QAbstractButton, això vol dir que podem utilitzar-los. En el nostre cas, volem fer clic.
buttonExportDocument.clicked.connect(self.exportDocument)
Si ara reiniciem el Krita, tindrem un acoblador nou i en aquest hi haurà un botó. En fer-hi clic s'activarà la funció d'exportació.
No obstant això, el botó es veu alineat de manera una mica estranya. Això és perquè el nostre mainWidget
no té disposició. Fem-ho ràpidament:
mainWidget.setLayout(QVBoxLayout())
mainWidget.layout().addWidget(buttonExportDocument)
Les Qt tenen diverses disposicions, però «QHBoxLayout» i «QVBoxLayout» són les més fàcils d'utilitzar, simplement organitzen els ginys de forma horitzontal o vertical.
Reinicieu el Krita i el botó hauria d'estar present.
Senyals i ranures de PyQt¶
Ja hem estat emprant senyals i ranures de PyQt, però hi ha ocasions en les quals voldreu crear els vostres propis senyals i ranures. Com la documentació de PyQt és força difícil d'entendre, i la forma en què es creen els senyals i les ranures és molt diferent de C++ de les Qt, ho expliquem aquí:
Totes les funcions de Python que realitzeu al PyQt es poden entendre com ranures, el qual vol dir que poden connectar-se a senyals com Action.triggered
o QPushButton.clicked
. No obstant això, la QCheckBox
té un senyal per a alternar, la qual envia un booleà. Com aconseguim que la nostra funció l'accepti?
Primer, assegureu-vos de tenir la importació correcta per a crear les ranures personalitzades:
from PyQt5.QtCore import pyqtSlot
(Si hi ha importació des de from PyQt5.QtCore import *
ja a la llista d'importacions, llavors no haureu de fer això, és clar).
Després, haureu d'afegir una definició de ranura de PyQt abans de la vostra funció:
@pyqtSlot(bool)
def myFunction(self, enabled):
enabledString = "disabled"
if (enabled == True):
enabledString = "enabled"
print("La casella de selecció és"+enabledString)
Després, quan hàgiu creat la casella de selecció, podreu fer quelcom com «myCheckbox.toggled.connect(self.myFunction)».
De manera similar, per a crear els vostres propis senyals de PyQt, feu el següent:
# el nom del senyal s'afegeix a les variables membres de la classe
signal_name = pyqtSignal(bool, name='signalName')
def emitMySignal(self):
# I així és com s'activa el senyal a emetre.
self.signal_name.emit(True)
I utilitzeu la importació correcta:
from PyQt5.QtCore import pyqtSignal
Per a emetre o crear ranures per a objectes que no són objectes estàndard de Python, només haureu de posar els seus noms entre cometes.
Una nota sobre les proves d'una unitat¶
Si voleu escriure proves de la unitat per al vostre connector, mireu al mòdul «mock» del Krita.
Conclusió¶
Bé, això cobreix tots els detalls específics del Krita per a crear connectors en Python. No maneja com analitzar les dades dels píxels o les millors pràctiques amb els documents, però si teniu una mica d'experiència amb Python, hauríeu de poder començar a crear els vostres propis connectors.
Com sempre, llegiu el codi amb cura i els documents de l'API per a Python, el Krita i les Qt per a veure què és possible, i arribareu molt lluny.