fix: окно расчёта показателей 8/9 — не уходит на задний план, ввод работает, кнопка на месте
Проблемы: 1. Окно уходило на задний план при сдвиге — не было grab_set/lift, родитель указывал на главное окно вместо диалога ПП 127 2. В показателе 8 не вводились данные — из-за потери фокуса 3. В показателе 9 кнопка «Рассчитать» не была видна — окно 720x560 не вмещало все поля (прибыль/налог/ΔДоходов/бюджет/НДПИ/ДИВ/ВСО/НС + результат), кнопки уезжали за край Исправлено: - родитель окна — dialog (ПП 127), а не root - w.transient(dialog) + w.lift() + w.grab_set() + w.focus_force() - тело окна в Canvas + вертикальный Scrollbar (все поля доступны) - кнопки «🧮 Рассчитать / ✔️ Применить / Отмена» вне скролла — всегда видны - при закрытии — grab_release()
This commit is contained in:
+38
-16
@@ -2172,23 +2172,38 @@ class DokoGenApp:
|
||||
profit = getattr(self.model, 'profit', '') or ''
|
||||
profit_tax = getattr(self.model, 'profit_tax', '') or ''
|
||||
|
||||
w = tk.Toplevel(self.root)
|
||||
# Родитель — окно ПП 127 (dialog), а не главное окно;
|
||||
# grab_set + lift — чтобы окно не уходило на задний план
|
||||
w = tk.Toplevel(dialog)
|
||||
w.title(f"🧮 Авторасчёт показателя {num} — {name[:60]}")
|
||||
w.geometry("720x560")
|
||||
w.transient(self.root)
|
||||
frm = ttk.Frame(w, padding=10)
|
||||
frm.pack(fill=tk.BOTH, expand=True)
|
||||
w.geometry("820x700")
|
||||
w.transient(dialog)
|
||||
w.lift()
|
||||
w.focus_force()
|
||||
|
||||
# Внешняя рамка: тело со скроллом + кнопки снизу (всегда видны)
|
||||
outer = ttk.Frame(w, padding=10)
|
||||
outer.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
canvas = tk.Canvas(outer, highlightthickness=0)
|
||||
scrollbar = ttk.Scrollbar(outer, orient=tk.VERTICAL, command=canvas.yview)
|
||||
frm = ttk.Frame(canvas)
|
||||
frm.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
|
||||
canvas.create_window((0, 0), window=frm, anchor="nw")
|
||||
canvas.configure(yscrollcommand=scrollbar.set)
|
||||
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
||||
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||
|
||||
if num == '9':
|
||||
ttk.Label(frm, text="Показатель 9 — ущерб бюджетам РФ (применим ко всем субъектам КИИ)",
|
||||
font=('Arial', 10, 'bold')).pack(anchor=tk.W)
|
||||
ttk.Label(frm, text="Формула: №9 = ΔБ / Бусредн × 100%, где ΔБ = ΔНП + ΔНДПИ + ΔДИВ + ΔВСО + ΔНС\n"
|
||||
"ΔНП = ΔДоходов × (налог на прибыль / прибыль); если ΔДоходов > прибыли — весь налог.",
|
||||
foreground='gray', wraplength=660, justify=tk.LEFT).pack(anchor=tk.W, pady=(2, 6))
|
||||
foreground='gray', wraplength=760, justify=tk.LEFT).pack(anchor=tk.W, pady=(2, 6))
|
||||
|
||||
def _row(label, key, default=''):
|
||||
ttk.Label(frm, text=label).pack(anchor=tk.W, pady=(4, 0))
|
||||
e = ttk.Entry(frm, width=60)
|
||||
e = ttk.Entry(frm, width=70)
|
||||
e.insert(0, str(default or ''))
|
||||
e.pack(fill=tk.X)
|
||||
return e
|
||||
@@ -2204,18 +2219,18 @@ class DokoGenApp:
|
||||
e_div = _row("Снижение выплат от дивидендов ΔДИВ (руб.):", 'div', '0')
|
||||
e_vso = _row("Снижение выплат сторонних организаций ΔВСО (руб.):", 'vso', '0')
|
||||
e_ns = _row("Снижение сборов ΔНС (руб.):", 'ns', '0')
|
||||
result = tk.Text(frm, height=10, wrap=tk.WORD, state=tk.NORMAL)
|
||||
result = tk.Text(frm, height=8, wrap=tk.WORD, state=tk.NORMAL)
|
||||
result.pack(fill=tk.BOTH, expand=True, pady=(8, 0))
|
||||
else:
|
||||
ttk.Label(frm, text="Показатель 8 — ущерб субъекту КИИ",
|
||||
font=('Arial', 10, 'bold')).pack(anchor=tk.W)
|
||||
ttk.Label(frm, text="Применим только для: госкорпорации, ГУП, госкомпании, стратегического АО/предприятия "
|
||||
"(Указ Президента № 1009).\nФормула: №8 = ΔДоходов / Дусредн × 100%.",
|
||||
foreground='gray', wraplength=660, justify=tk.LEFT).pack(anchor=tk.W, pady=(2, 6))
|
||||
foreground='gray', wraplength=760, justify=tk.LEFT).pack(anchor=tk.W, pady=(2, 6))
|
||||
|
||||
def _row(label, key, default=''):
|
||||
ttk.Label(frm, text=label).pack(anchor=tk.W, pady=(4, 0))
|
||||
e = ttk.Entry(frm, width=60)
|
||||
e = ttk.Entry(frm, width=70)
|
||||
e.insert(0, str(default or ''))
|
||||
e.pack(fill=tk.X)
|
||||
return e
|
||||
@@ -2230,7 +2245,7 @@ class DokoGenApp:
|
||||
'dincome', f"{_d_loss:,.0f}" if _d_loss else '')
|
||||
e_budget = _row("Доходы субъекта КИИ, усреднённые за 5 лет (руб.):",
|
||||
'budget', f"{_d_avg:,.0f}" if _d_avg else '')
|
||||
result = tk.Text(frm, height=10, wrap=tk.WORD, state=tk.NORMAL)
|
||||
result = tk.Text(frm, height=8, wrap=tk.WORD, state=tk.NORMAL)
|
||||
result.pack(fill=tk.BOTH, expand=True, pady=(8, 0))
|
||||
|
||||
def _calc():
|
||||
@@ -2240,7 +2255,7 @@ class DokoGenApp:
|
||||
b = _num(e_budget.get())
|
||||
if d is None or b is None or b <= 0:
|
||||
result.delete('1.0', tk.END)
|
||||
result.insert('1.0', "Заполните оба поля (ΔДоходов и Дусредн).")
|
||||
result.insert('1.0', "Заполните оба поля (ущерб и доходы за 5 лет).")
|
||||
return
|
||||
val = d / b * 100
|
||||
lines.append(f"Суммарный экономический ущерб от нарушения критических процессов: {d:,.0f} руб.")
|
||||
@@ -2316,12 +2331,10 @@ class DokoGenApp:
|
||||
elif 'Категория значимости: III' in cat_line:
|
||||
cat = 'III'
|
||||
if cat:
|
||||
# Выбрать в комбобоксе соответствующую категорию
|
||||
opts = list(combo['values'])
|
||||
target = next((o for o in opts if o.startswith(f"{cat} категория")), None)
|
||||
if target:
|
||||
var.set(target)
|
||||
# Обоснование с расчётом
|
||||
prefix = f"Показатель {num}. {name} — {cat} категория."
|
||||
full = prefix + "\n" + txt
|
||||
cur = justify_txt.get('1.0', 'end-1c').strip()
|
||||
@@ -2340,14 +2353,23 @@ class DokoGenApp:
|
||||
justify_txt.insert('end', '\n' + full)
|
||||
else:
|
||||
justify_txt.insert('1.0', full)
|
||||
w.grab_release()
|
||||
w.destroy()
|
||||
|
||||
btns = ttk.Frame(frm)
|
||||
# Кнопки — вне скролла, всегда видны
|
||||
btns = ttk.Frame(outer)
|
||||
btns.pack(fill=tk.X, pady=(8, 0))
|
||||
ttk.Button(btns, text="🧮 Рассчитать", command=_calc).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(btns, text="✔️ Применить категорию", command=_apply).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(btns, text="Отмена", command=w.destroy).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(btns, text="Отмена",
|
||||
command=lambda: (w.grab_release(), w.destroy())).pack(side=tk.LEFT, padx=2)
|
||||
|
||||
# Захват фокуса — окно не уходит на задний план
|
||||
try:
|
||||
w.grab_set()
|
||||
except Exception:
|
||||
pass
|
||||
w.lift()
|
||||
|
||||
rows = [] # (num, name, values{III:..,II:..,I:..}, var, applicable)
|
||||
_combos = {} # num -> комбобокс (для автозаполнения)
|
||||
|
||||
Reference in New Issue
Block a user