На самом деле довольно просто. Некоторый код, который я написал для вывода иерархии слоев изображения:
def dump(parent,level,dumpList):
prefix=' '*level
for pos,layerOrGroup in enumerate(parent.layers):
dumpList.append(prefix+layerOrGroup.name)
if isinstance(layerOrGroup,gimp.GroupLayer):
dump(layerOrGroup,level+1,dumpList)
def dumpLayerHierarchy(image):
dumpList=[]
dump(image,0,dumpList)
gimp.message('\n'.join(dumpList))
Две вещи, которые нужно знать:
- Группа слоев является экземпляром
gimp.GroupLayer
(обычный layer gimp.Layer
) - duck-typing в своих лучших проявлениях, и у
gimp.Image
, и у gimp.GroupLayer
есть дочерние элементы в атрибуте layers
, так что вам даже не нужно специально писать первый случай уровень, на котором вы начинаете с самого изображения.
PS: лучше регистрация:
register(
"search-replace-layer-names",
"Search/Replace in Layer Names",
"Search/Replace in Layer Names...",
"stigzler",
"stigzler",
"2020",
"Replace Layer Names...",
"*",
[
(PF_IMAGE,"image", "Image:", None),
(PF_DRAWABLE, "drawable", "Drawable:", None),
(PF_STRING, "searchterm", "Search for Term:", "SearchTerm"),
(PF_STRING, "replaceterm", "Replace With:", "ReplaceWith"),
(PF_TOGGLE, "applyvisible", "Only Apply to visible layers:", 0),
(PF_TOGGLE, "casesensative", "Case sensative:", 0)
],
[],
python_search_replace_layer_names
menu="<Image>/Edit/Search and Replace/"
)
Изменения:
- Cosmeti c: сделать «атом» более стандартный. «python -fu» добавлено Gimp в любом случае
- Измените объявление меню на не устаревший тип с отдельным пунктом меню и расположением меню
- Сделайте тип изображения
"*"
для поддержки всех изображений типы (ваш код не будет работать с индексированными изображениями) - Сделайте параметры Image и Drawable явными. Это иногда полезно. Так как вы, скорее всего, не используете слой / Drawable в любом случае, вы можете удалить его из списка параметров (и из прототипа вашей функции).
Other:
- Вы надеваете вам не нужно нажимать / вставлять контекст, так как вы не изменяете контекст
- Вам не нужно копировать слои изображения (
image.layers[::-1]
) или даже изменять их, поскольку вы просто обновляете атрибуты (если вы удаление слоев было бы другим делом) - Отмена группы - это хорошо, но вы можете заключить в скобки свой код в попытке / за исключением того, что в случае проблем группа отмены будет правильно закрыта, и вы все равно сможете легко отменить частичные изменения:
import traceback # To still get source code location
def the_plugin(image,layer):
image.undo_group_start()
try:
# Your code goes here
except Exception as e:
trace(e.args[0])
gimp.message(e.args[0]+':'+traceback.format_exc())
image.undo_group_end()
Исправлен ваш код:
import re,traceback
from gimpfu import *
def python_search_replace_layer_names(image,searchterm, replaceterm, applyvisible, casesensitive) :
image.undo_group_start()
try:
searchtermRegEx = re.compile(re.escape(searchterm),0 if casesensitive else re.IGNORECASE)
renameLayers(image,searchtermRegEx,replaceterm,applyvisible)
except Exception as e:
gimp.message(e.args[0]+':'+traceback.format_exc())
image.undo_group_end()
def renameLayers(parent,searchtermRegEx,replaceterm,applyvisible):
for pos,layerOrGroup in enumerate(parent.layers):
if not applyvisible or layerOrGroup.visible:
layerName = searchtermRegEx.sub(replaceterm, layerOrGroup.name)
layerOrGroup.name = layerName
if isinstance(layerOrGroup,gimp.GroupLayer):
renameLayers(layerOrGroup,searchtermRegEx,replaceterm,applyvisible)
register(
"search-replace-layer-names",
"Search/Replace in Layer Names",
"Search/Replace in Layer Names...",
"stigzler",
"stigzler",
"2020",
"Replace Layer Names...",
"*",
[
(PF_IMAGE,"image", "Image:", None),
(PF_STRING, "searchterm", "Search for Term:", "SearchTerm"),
(PF_STRING, "replaceterm", "Replace With:", "ReplaceWith"),
(PF_TOGGLE, "applyvisible", "Only Apply to visible layers:", 0),
(PF_TOGGLE, "casesensitive", "Case sensative:", 0)
],
[],
python_search_replace_layer_names,
menu="<Image>/Edit/Search and Replace/")
main()
Исправления:
- добавьте пропущенную запятую в конце
python_search_replace_layer_names
в регистрация - добавлена
traceback
импорт - удален вызов функции
trace
(только в моем собственном коде) - удалено много ненужных импортов
- удалено
layer
параметр для функции плагина - удален
level
параметр для рекурсии function - некоторый код сделал больше pythoni c
Кроме того, слой в группе может быть невидимым либо потому, что он сам невидим (layer.visible
ложно), либо потому, что группа невидима. Ваш текущий код не учитывает невидимость, вызванную группой.
Наконец, некоторые подсказки для отладки скриптов Gimp python (с некоторым акцентом на Windows) можно найти здесь .