Compare commits
16
Commits
7828684b7d
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d57dbe0e5 | ||
|
|
12f94d0927 | ||
|
|
d68eef4bbe | ||
|
|
6ccea72dff | ||
|
|
fb01a14c37 | ||
|
|
5efc3a0e99 | ||
|
|
771bc6987f | ||
|
|
faf675e861 | ||
|
|
7ebcf04f63 | ||
|
|
3134d19089 | ||
|
|
dff3f7b971 | ||
|
|
307f632363 | ||
|
|
9d156bfc0d | ||
|
|
5d7d727ef9 | ||
|
|
2c3d25e790 | ||
|
|
5c75a72b51 |
@@ -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
|
||||
@@ -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',
|
||||
)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
+26
-10
@@ -34,6 +34,7 @@ class DokoGenApp:
|
||||
root.title("ДоКоГеНеРаТоР — 152-ФЗ (Персональные данные)")
|
||||
root.geometry("1200x800")
|
||||
root.minsize(900, 600)
|
||||
self._set_app_icon()
|
||||
|
||||
self.model = Company()
|
||||
self.current_file: Optional[str] = None
|
||||
@@ -81,6 +82,26 @@ class DokoGenApp:
|
||||
self._load_autosave()
|
||||
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):
|
||||
menubar = tk.Menu(self.root)
|
||||
@@ -315,16 +336,11 @@ class DokoGenApp:
|
||||
apply_row = ttk.Frame(right)
|
||||
apply_row.pack(fill=tk.X, pady=(4, 0))
|
||||
ttk.Label(apply_row, text="Подставлять:", font=('', 8)).pack(side=tk.LEFT, padx=(0, 4))
|
||||
ttk.Checkbutton(apply_row, text="склонения", variable=self._apply_flags['declension'],
|
||||
font=('', 8)).pack(side=tk.LEFT)
|
||||
ttk.Checkbutton(apply_row, text="кр. склон.", variable=self._apply_flags['short_declension'],
|
||||
font=('', 8)).pack(side=tk.LEFT)
|
||||
ttk.Checkbutton(apply_row, text="адрес", variable=self._apply_flags['address'],
|
||||
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)
|
||||
ttk.Checkbutton(apply_row, text="склонения", variable=self._apply_flags['declension']).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['address']).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['chief']).pack(side=tk.LEFT)
|
||||
self._verify_result = None
|
||||
|
||||
# ---------- ПРОВЕРКА ДАННЫХ (Морфер / DaData / ИИ) ----------
|
||||
|
||||
Reference in New Issue
Block a user