05/23 Phase 16
This commit is contained in:
@@ -23,6 +23,7 @@ from core.predictor import (
|
||||
)
|
||||
from core.checker import check_ticket, parse_numbers
|
||||
from core.exporter import export_predictions_excel, export_predictions_csv, ensure_exports_dir
|
||||
from ui.widgets import BallsBar
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -137,6 +138,13 @@ class PredictorScreen(ttk.Frame):
|
||||
self._tree.pack(side="left", fill="both", expand=True)
|
||||
vsb.pack(side="right", fill="y")
|
||||
|
||||
self._tree.bind("<<TreeviewSelect>>", self._on_gen_row_select)
|
||||
|
||||
# ── Ball detail strip ─────────────────────────────────────────────────
|
||||
ttk.Separator(parent, orient="horizontal").pack(fill="x", padx=6)
|
||||
self._gen_detail = ttk.Frame(parent, padding=(8, 3))
|
||||
self._gen_detail.pack(fill="x")
|
||||
|
||||
# Bottom bar
|
||||
bottom = ttk.Frame(parent, padding=(6, 4))
|
||||
bottom.pack(fill="x")
|
||||
@@ -352,9 +360,28 @@ class PredictorScreen(ttk.Frame):
|
||||
self._refresh_saved()
|
||||
logger.info("[PREDICT] Saved %d prediction(s) to DB", saved)
|
||||
|
||||
def _on_gen_row_select(self, _event=None):
|
||||
for w in self._gen_detail.winfo_children():
|
||||
w.destroy()
|
||||
sel = self._tree.selection()
|
||||
if not sel:
|
||||
return
|
||||
vals = self._tree.item(sel[0], "values")
|
||||
# vals: (#, numbers_fmt, bonus)
|
||||
try:
|
||||
nums = [int(x) for x in str(vals[1]).split() if x.isdigit()]
|
||||
b_txt = str(vals[2])
|
||||
bonus = int(b_txt) if b_txt.isdigit() else None
|
||||
except Exception:
|
||||
return
|
||||
if nums:
|
||||
BallsBar(self._gen_detail, numbers=nums, bonus=bonus).pack(anchor="w")
|
||||
|
||||
def _clear(self):
|
||||
self._tickets = []
|
||||
self._tree.delete(*self._tree.get_children())
|
||||
for w in self._gen_detail.winfo_children():
|
||||
w.destroy()
|
||||
self._save_btn.config(state="disabled")
|
||||
self._status_var.set("")
|
||||
|
||||
@@ -491,6 +518,13 @@ class PredictorScreen(ttk.Frame):
|
||||
self._chk_tree.tag_configure("high", foreground="#1e8449")
|
||||
self._chk_tree.tag_configure("low", foreground="#555555")
|
||||
|
||||
self._chk_tree.bind("<<TreeviewSelect>>", self._on_chk_row_select)
|
||||
|
||||
# ── Ball detail strip ─────────────────────────────────────────────────
|
||||
ttk.Separator(parent, orient="horizontal").pack(fill="x", padx=6)
|
||||
self._chk_detail = ttk.Frame(parent, padding=(8, 3))
|
||||
self._chk_detail.pack(fill="x")
|
||||
|
||||
# Summary label
|
||||
self._chk_summary_var = tk.StringVar()
|
||||
ttk.Label(parent, textvariable=self._chk_summary_var,
|
||||
@@ -569,11 +603,64 @@ class PredictorScreen(ttk.Frame):
|
||||
f"{total} draw{'s' if total != 1 else ''} matched • Best: {best}"
|
||||
)
|
||||
|
||||
def _on_chk_row_select(self, _event=None):
|
||||
for w in self._chk_detail.winfo_children():
|
||||
w.destroy()
|
||||
sel = self._chk_tree.selection()
|
||||
if not sel:
|
||||
return
|
||||
vals = self._chk_tree.item(sel[0], "values")
|
||||
# vals: (date, draw_numbers_fmt, bonus, main_hits, bonus_hit, tier)
|
||||
try:
|
||||
draw_nums = [int(x) for x in str(vals[1]).split() if x.isdigit()]
|
||||
db_txt = str(vals[2])
|
||||
draw_bonus = int(db_txt) if db_txt.isdigit() else None
|
||||
except Exception:
|
||||
return
|
||||
if not draw_nums:
|
||||
return
|
||||
|
||||
# Ticket numbers from the input entries
|
||||
try:
|
||||
ticket_nums = parse_numbers(self._chk_nums_var.get())
|
||||
except Exception:
|
||||
ticket_nums = []
|
||||
raw_b = self._chk_bonus_var.get().strip()
|
||||
ticket_bonus = int(raw_b) if raw_b.isdigit() else None
|
||||
|
||||
ticket_set = set(ticket_nums)
|
||||
draw_set = set(draw_nums)
|
||||
_GREEN = ("#27ae60", "#ffffff")
|
||||
_GREY = ("#cccccc", "#888888")
|
||||
|
||||
ticket_hi = {n: (_GREEN if n in draw_set else _GREY) for n in ticket_nums}
|
||||
draw_hi = {n: _GREEN for n in draw_nums if n in ticket_set}
|
||||
if ticket_bonus is not None:
|
||||
ticket_hi[ticket_bonus] = (
|
||||
_GREEN if draw_bonus is not None and ticket_bonus == draw_bonus else _GREY
|
||||
)
|
||||
if draw_bonus is not None and ticket_bonus is not None and draw_bonus == ticket_bonus:
|
||||
draw_hi[draw_bonus] = _GREEN
|
||||
|
||||
grid = ttk.Frame(self._chk_detail)
|
||||
grid.pack(anchor="w")
|
||||
if ticket_nums:
|
||||
ttk.Label(grid, text="Ticket:", foreground="#555555",
|
||||
font=("TkDefaultFont", 8), width=7).grid(row=0, column=0, sticky="w")
|
||||
BallsBar(grid, numbers=ticket_nums, bonus=ticket_bonus,
|
||||
highlights=ticket_hi).grid(row=0, column=1, sticky="w")
|
||||
ttk.Label(grid, text="Draw:", foreground="#555555",
|
||||
font=("TkDefaultFont", 8), width=7).grid(row=1, column=0, sticky="w")
|
||||
BallsBar(grid, numbers=draw_nums, bonus=draw_bonus,
|
||||
highlights=draw_hi).grid(row=1, column=1, sticky="w")
|
||||
|
||||
def _clear_check(self):
|
||||
self._chk_nums_var.set("")
|
||||
self._chk_bonus_var.set("")
|
||||
self._chk_status_var.set("")
|
||||
self._chk_tree.delete(*self._chk_tree.get_children())
|
||||
for w in self._chk_detail.winfo_children():
|
||||
w.destroy()
|
||||
self._chk_summary_var.set("")
|
||||
|
||||
def _load_check_games(self):
|
||||
|
||||
Reference in New Issue
Block a user