/
kuzminaa
/
PDM
Обзор
Документация
Войти
/
kuzminaa
/
PDM
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/preview_engine.py
97 строк
4 KB
kuzminaa
refactor: migrate modules to src/, add logging system, add assembly workshop
29 июл 2026, 23:52
29 июл 2026, 23:52
a5323aa
Код
Авторство
О чём код?
# -*- coding: utf-8 -*- """ Модуль: preview_engine.py Назначение: Универсальный движок превью PDF-документов ЕСКД на чистом Tkinter. Исключает зависимость от PIL (Pillow). Совместим с Debian 13 и Manjaro. """ import os import logging import tkinter as tk import fitz # PyMuPDF from . import db_manager as db logger = logging.getLogger(__name__) class PDFPreviewEngine: """Движок управления страницами и кросс-платформенного рендеринга PDF.""" def __init__(self, app_instance=None): self.app = app_instance self.selected_pdf = "" self.current_md5 = "" self.current_page = 0 self.total_pages = 0 self.current_preview_img = None def load_pdf(self, path): """Загружает файл, считает MD5 и возвращает статус успеха.""" if not path or not os.path.exists(path): return False try: self.selected_pdf = path self.current_md5 = db.calculate_md5(path) # Открываем документ для считывания количества страниц doc = fitz.open(self.selected_pdf) self.total_pages = len(doc) self.current_page = 0 doc.close() return True except Exception: return False def render_current_page(self, lbl_widget, lbl_counter_widget): """ Рендерит выбранную страницу на UI-метку без использования PIL. Кросс-платформенная совместимость (Debian / Manjaro). """ if not self.selected_pdf: return try: with fitz.open(self.selected_pdf) as doc: if len(doc) == 0: return page = doc[self.current_page] # Оптимальный коэффициент масштабирования под размеры панели в layout.py pix = page.get_pixmap(matrix=fitz.Matrix(0.75, 0.75)) # Универсальное извлечение PNG-байтов для Tkinter в зависимости от версии PyMuPDF if hasattr(pix, "tobytes"): img_data = pix.tobytes("png") elif hasattr(pix, "pdf_data"): img_data = pix.pdf_data(format="png") else: img_data = pix.getImageData(format="png") # Создаем нативный PhotoImage из байтовой строки self.current_preview_img = tk.PhotoImage(data=img_data) # Обновляем виджеты слоя представления layout.py lbl_widget.config(image=self.current_preview_img, text="") lbl_counter_widget.config(text=f"Страница: {self.current_page + 1} / {self.total_pages}") except Exception as e: lbl_widget.config(image="", text=f"Ошибка навигации/рендеринга:\n{e}") def next_page(self): """Инкремент страницы.""" if self.selected_pdf and self.current_page < (self.total_pages - 1): self.current_page += 1 return True return False def prev_page(self): """Декремент страницы.""" if self.selected_pdf and self.current_page > 0: self.current_page -= 1 return True return False def clear(self): """Очистка ресурсов движка.""" self.selected_pdf = "" self.current_md5 = "" self.current_page = 0 self.total_pages = 0 self.current_preview_img = None