16 Commits
Author SHA1 Message Date
prog1764 9d57dbe0e5 Удалён архив После генерации.rar (перенесён на сервер) 2026-08-03 22:55:04 +04:00
prog1764 12f94d0927 Удалён архив Шаблоны.rar (перенесён на сервер) 2026-08-03 22:55:02 +04:00
kneon223557 d68eef4bbe Загрузить файлы в «/» 2026-08-03 22:45:36 +04:00
prog1764 6ccea72dff fix: _set_app_icon разрывал __init__ (NameError: root is not defined) 2026-08-03 22:29:54 +04:00
prog1764 fb01a14c37 feat: иконка на окне программы (заголовок/панель задач) + в ресурсах exe 2026-08-03 22:02:32 +04:00
prog1764 5efc3a0e99 feat: иконка — 64/128px из нового оригинала (512x512) 2026-08-03 21:59:26 +04:00
prog1764 771bc6987f feat: иконка — 48px из нового оригинала (512) 2026-08-03 21:58:11 +04:00
prog1764 faf675e861 feat: иконка — 48px из отдельного оригинала (все размеры из своих файлов) 2026-08-03 21:56:50 +04:00
prog1764 7ebcf04f63 feat: иконка — каждый размер из отдельного оригинала (16/24/32/48/64/128/256) 2026-08-03 21:56:02 +04:00
prog1764 3134d19089 feat: иконка — все размеры из оригинальных рисунков (16px отдельный, 24-32 из малого, 48-256 из большого) 2026-08-03 21:55:11 +04:00
prog1764 dff3f7b971 feat: иконка — комбинированный ICO (мелкие 16-32 из малого рисунка, крупные 48-256 из большого) 2026-08-03 21:53:56 +04:00
prog1764 307f632363 feat: иконка 1024x1024 (ICO 16-256px) для exe 2026-08-03 21:52:29 +04:00
prog1764 9d156bfc0d feat: иконка приложения (dokogen/icon.ico) подключена к сборке 2026-08-03 21:49:12 +04:00
prog1764 5d7d727ef9 fix: build_exe.bat переписан в ASCII (кириллица в UTF-8 ломала cmd) 2026-08-03 21:30:56 +04:00
prog1764 2c3d25e790 feat: сборка в exe (PyInstaller)
- dokogen.spec: упаковка dictionaries/, data/, словарей pymorphy3,
  скрытые импорты lxml/openpyxl; один файл dist/DokoGen.exe
- build_exe.bat: установка PyInstaller + зависимостей + сборка
2026-08-03 20:35:17 +04:00
prog1764 5c75a72b51 fix: ttk.Checkbutton не принимает опцию font (TclError unknown option) 2026-08-03 20:27:59 +04:00
4 changed files with 132 additions and 10 deletions
+43
View File
@@ -0,0 +1,43 @@
@echo off
chcp 65001 >nul
title Build DokoGen.exe
echo ============================================
echo Building DokoGen into a single EXE file
echo ============================================
echo.
cd /d "%~dp0"
echo [1/3] Installing PyInstaller...
py -m pip install --upgrade pyinstaller
if errorlevel 1 (
echo ERROR: failed to install PyInstaller
pause
exit /b 1
)
echo.
echo [2/3] Installing dependencies...
py -m pip install -r requirements.txt
if errorlevel 1 (
echo ERROR: failed to install dependencies
pause
exit /b 1
)
echo.
echo [3/3] Building DokoGen.exe (1-3 minutes)...
py -m PyInstaller --clean --noconfirm dokogen.spec
if errorlevel 1 (
echo ERROR: build failed
pause
exit /b 1
)
echo.
echo ============================================
echo DONE! File: dist\DokoGen.exe
echo Copy it to any Windows PC and run it.
echo Python is NOT required on target PC.
echo ============================================
pause
+63
View File
@@ -0,0 +1,63 @@
# -*- mode: python ; coding: utf-8 -*-
"""DokoGen spec для PyInstaller.
Сборка: py -m PyInstaller --clean --noconfirm dokogen.spec
Результат: dist/DokoGen.exe (один файл, запускается на любом Windows без Python).
"""
import sys
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
# ---------- Данные приложения ----------
datas = [
# Справочники (defense_tools.json, pd_actions.json, pd_items.json, pd_categories.json)
('dokogen/dictionaries', 'dokogen/dictionaries'),
# Пустой опросник 152-ФЗ (для «Справка → Пустой опросник»)
('dokogen/data', 'dokogen/data'),
# Иконка приложения (для окна программы в exe)
('dokogen/icon.ico', 'dokogen'),
]
# ---------- Словари pymorphy3 (обязательно!) ----------
# Без них склонение организаций/ФИО в exe не будет работать.
datas += collect_data_files('pymorphy3_dicts_ru')
datas += collect_data_files('pymorphy3')
# ---------- Скрытые импорты ----------
hiddenimports = collect_submodules('pymorphy3') + collect_submodules('pymorphy3_dicts_ru')
hiddenimports += [
'lxml', 'lxml.etree', 'lxml._elementpath',
'openpyxl', 'openpyxl.cell._writer',
]
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='DokoGen',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False, # GUI-приложение, без консоли
disable_windowed_traceback=False,
icon='dokogen/icon.ico',
)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

+26 -10
View File
@@ -34,6 +34,7 @@ class DokoGenApp:
root.title("ДоКоГеНеРаТоР — 152-ФЗ (Персональные данные)") root.title("ДоКоГеНеРаТоР — 152-ФЗ (Персональные данные)")
root.geometry("1200x800") root.geometry("1200x800")
root.minsize(900, 600) root.minsize(900, 600)
self._set_app_icon()
self.model = Company() self.model = Company()
self.current_file: Optional[str] = None self.current_file: Optional[str] = None
@@ -81,6 +82,26 @@ class DokoGenApp:
self._load_autosave() self._load_autosave()
self._start_autosave_timer() self._start_autosave_timer()
def _set_app_icon(self):
"""Устанавливает иконку приложения на окно (заголовок, панель задач).
Работает и из исходников, и из exe (frozen):
- исходники: dokogen/icon.ico рядом с модулем
- exe: dokogen/icon.ico из _MEIPASS (ресурсы PyInstaller)
"""
try:
if getattr(sys, 'frozen', False):
base = getattr(sys, '_MEIPASS', os.path.dirname(sys.executable))
ico = os.path.join(base, 'dokogen', 'icon.ico')
if not os.path.exists(ico):
ico = os.path.join(os.path.dirname(sys.executable), 'icon.ico')
else:
ico = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icon.ico')
if os.path.exists(ico):
self.root.iconbitmap(ico)
except Exception:
pass
# ==================== МЕНЮ ==================== # ==================== МЕНЮ ====================
def _build_menu(self): def _build_menu(self):
menubar = tk.Menu(self.root) menubar = tk.Menu(self.root)
@@ -315,16 +336,11 @@ class DokoGenApp:
apply_row = ttk.Frame(right) apply_row = ttk.Frame(right)
apply_row.pack(fill=tk.X, pady=(4, 0)) apply_row.pack(fill=tk.X, pady=(4, 0))
ttk.Label(apply_row, text="Подставлять:", font=('', 8)).pack(side=tk.LEFT, padx=(0, 4)) ttk.Label(apply_row, text="Подставлять:", font=('', 8)).pack(side=tk.LEFT, padx=(0, 4))
ttk.Checkbutton(apply_row, text="склонения", variable=self._apply_flags['declension'], ttk.Checkbutton(apply_row, text="склонения", variable=self._apply_flags['declension']).pack(side=tk.LEFT)
font=('', 8)).pack(side=tk.LEFT) ttk.Checkbutton(apply_row, text="кр. склон.", variable=self._apply_flags['short_declension']).pack(side=tk.LEFT)
ttk.Checkbutton(apply_row, text="кр. склон.", variable=self._apply_flags['short_declension'], ttk.Checkbutton(apply_row, text="адрес", variable=self._apply_flags['address']).pack(side=tk.LEFT)
font=('', 8)).pack(side=tk.LEFT) ttk.Checkbutton(apply_row, text="ИНН/КПП/ОГРН", variable=self._apply_flags['requisites']).pack(side=tk.LEFT)
ttk.Checkbutton(apply_row, text="адрес", variable=self._apply_flags['address'], ttk.Checkbutton(apply_row, text="руковод.", variable=self._apply_flags['chief']).pack(side=tk.LEFT)
font=('', 8)).pack(side=tk.LEFT)
ttk.Checkbutton(apply_row, text="ИНН/КПП/ОГРН", variable=self._apply_flags['requisites'],
font=('', 8)).pack(side=tk.LEFT)
ttk.Checkbutton(apply_row, text="руковод.", variable=self._apply_flags['chief'],
font=('', 8)).pack(side=tk.LEFT)
self._verify_result = None self._verify_result = None
# ---------- ПРОВЕРКА ДАННЫХ (Морфер / DaData / ИИ) ---------- # ---------- ПРОВЕРКА ДАННЫХ (Морфер / DaData / ИИ) ----------