Программно создать метку к изображению в документе врайтер

Автор Ципихович Эндрю, 24 марта 2026, 09:01

0 Пользователи и 1 гость просматривают эту тему.

Ципихович Эндрю

здравствуйте
изображение в документ врайтер вставляется макросом с файла, есть файл:
image_path = r"C:\Users\start\AppData\Roaming\LibreOffice\4\user\Scripts\python\output.svg"
как изображение пометить меткой? как потом считать эту метку?

смысл в том, что нужно создать метку не к файлу так как он будет удалён, а именно к изображению, в документе я это изображение естественно могу копировать и вставлять в нужное место множество раз и тогда эта метка не сотрётся? спасибо

sokol92

Посмотрите эту тему на "большом" форуме.
Предлагается использовать метод setName() графического объекта.
Попробуйте самостоятельно написать скрипт.
Владимир.

Ципихович Эндрю

здравствуйте, добавил изображение, поставил метки:
import uno
import os

def Message_box(title, text):
    try:
        ctx = uno.getComponentContext()
        smgr = ctx.ServiceManager
        toolkit = smgr.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
        desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
        frame = desktop.getCurrentFrame()
        window = frame.getContainerWindow()
        msgbox = toolkit.createMessageBox(window, 'infobox', 1, title, text)
        msgbox.execute()
        msgbox.dispose()
    except Exception as e:
        print(f"Ошибка показа сообщения: {e}")

def ProveritMetkiIzobrazheniy(event=None): # принимаем аргумент event, но можем игнорировать его-макрос будет работать если его запустить кнопкой или вручную
    # Получаем контекст текущего экземпляра LibreOffice
    local_ctx = uno.getComponentContext()
    smgr = local_ctx.ServiceManager

    # Получаем текущий документ
    desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', local_ctx)
    doc = desktop.getCurrentComponent()

    # Проверяем, что документ — Writer
    if not hasattr(doc, 'Text'):
        Message_box("Ошибка", "Документ не является текстовым (Writer)")
        return

    # Путь к изображению
    image_path = r"C:\Users\start\AppData\Roaming\LibreOffice\4\user\Scripts\python\output.svg"

    # Проверка существования файла
    if not os.path.exists(image_path):
        Message_box("Ошибка", f"Файл изображения не найден: {image_path}")
        return

    try:
        # Создаём графический объект через другой метод — более надёжный
        graphic_provider = smgr.createInstance("com.sun.star.graphic.GraphicProvider")

        # Загружаем изображение
        props = (
            uno.createUnoStruct("com.sun.star.beans.PropertyValue"),
        )
        props[0].Name = "URL"
        props[0].Value = uno.systemPathToFileUrl(image_path)

        graphic = graphic_provider.queryGraphic(props)

        if graphic is None:
            Message_box("Ошибка", "Не удалось загрузить изображение через GraphicProvider")
            return

        # Вставляем изображение как графический контент в текст
        text = doc.getText()
        cursor = text.createTextCursor()

        # Создаём объект для вставки
        graph_obj = doc.createInstance("com.sun.star.text.GraphicObject")
        graph_obj.Graphic = graphic
        graph_obj.AnchorType = uno.Enum(
            "com.sun.star.text.TextContentAnchorType",
            "AS_CHARACTER"
        )

        # Вставляем в документ
        text.insertTextContent(cursor, graph_obj, False)

        # Присваиваем метку (имя)
        label = "MY_IMAGE_LABEL"
        graph_obj.setName(label)

        Message_box("Успех", f"Изображение вставлено и помечено как: {label}")

    except Exception as e:
        Message_box("Критическая ошибка", f"Не удалось вставить изображение: {str(e)}")

g_exportedScripts = (ProveritMetkiIzobrazheniy,)

считал метки:

import uno      # Universal Network Objects - мост между Python и API LibreOffice
import winsound # Модуль для воспроизведения звукового сигнала

def Message_box(title, text):
    ctx = uno.getComponentContext()
    smgr = ctx.ServiceManager
    toolkit = smgr.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
    desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
    frame = desktop.getCurrentFrame()
    window = frame.getContainerWindow()
    msgbox = toolkit.createMessageBox(window, 1, 1, title, text)  # Тип: INFOBOX
    winsound.MessageBeep(winsound.MB_OK)
    msgbox.execute()
    msgbox.dispose()

def Count_images(_=None):
    ctx = uno.getComponentContext()
    smgr = ctx.ServiceManager
    desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
    doc = desktop.getCurrentComponent()

    if not doc.supportsService("com.sun.star.text.TextDocument"):
        Message_box("Ошибка", "Документ не является Writer-документом")
        return

    try:
        draw_pages = doc.getDrawPages()
        # 1. Сначала БЫСТРО считаем общее количество изображений
        total_images = sum(
            1 for page in draw_pages
            for i in range(page.getCount())
            if "com.sun.star.text.TextGraphicObject" in page.getByIndex(i).getSupportedServiceNames()
        )

        # 2. Если изображения найдены, выводим информацию о каждом
        if total_images > 0:
            current_image = 0
            for page_idx in range(draw_pages.getCount()):
                page = draw_pages.getByIndex(page_idx)
                for obj_idx in range(page.getCount()):
                    obj = page.getByIndex(obj_idx)
                    services = obj.getSupportedServiceNames()
                    if "com.sun.star.text.TextGraphicObject" in services:
                        current_image += 1

                        # Читаем метку объекта
                        try:
                            label = obj.getName()
                            if not label:
                                label = "Метка не задана"
                        except Exception:
                            label = "Ошибка чтения метки"

                        # Получаем графические свойства
                        try:
                            graphic = obj.Graphic
                            property_set_info = graphic.getPropertySetInfo()
                            properties = property_set_info.getProperties()
                            info_parts = []
                            for prop in properties:
                                try:
                                    value = str(graphic.getPropertyValue(prop.Name))
                                    info_parts.append(f"{prop.Name}: {value}")
                                except Exception as e:
                                    info_parts.append(f"{prop.Name}: Ошибка чтения ({e})")
                            info = "\n".join(info_parts)
                        except Exception as e:
                            info = f"Не удалось получить свойства изображения: {e}"

                        # Выводим окно для каждого изображения
                        Message_box(
                            f"Информация об изображении № {current_image} из {total_images}",
                            f"Метка: {label}\n\n{info}"
                        )
            return total_images

    except Exception as e:
        Message_box("Ошибка", f"Не удалось получить объекты: {str(e)}")
        return 0

    # Если цикл не был выполнен (изображений нет)
    Message_box("Подсчёт изображений", "В документе изображения не обнаружены")
    return 0

g_exportedScripts = (Count_images,)
получил Изображение 1, 2, 3...
какой из этих двух макросов лагает, или оба?