From b5b3cb7ecc66f5c1c8a00e96a23320dbfd6ddc80 Mon Sep 17 00:00:00 2001 From: ATATC Date: Sun, 14 Jul 2024 21:45:06 +0800 Subject: [PATCH 1/2] Supported using PIL images as Tkinter variables. (#278) --- leads_gui/photo.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/leads_gui/photo.py b/leads_gui/photo.py index c3a2a141..820c3258 100644 --- a/leads_gui/photo.py +++ b/leads_gui/photo.py @@ -1,21 +1,37 @@ from tkinter import Misc as _Misc, Event as _Event from typing import Callable as _Callable, override as _override +from PIL.Image import Image as _Image from PIL.ImageTk import PhotoImage as _PhotoImage -from customtkinter import StringVar as _StringVar +from customtkinter import Variable as _Variable, StringVar as _StringVar from leads_gui.prototype import CanvasBased, VariableControlled from leads_gui.types import Color as _Color from leads_video import base64_decode_image as _base64_decode_image +class ImageVariable(_Variable): + def __init__(self, master: _Misc, image: _Image, name: str | None = None) -> None: + super().__init__(master, False, name) + self._image: _Image = image + + @_override + def set(self, value: _Image) -> None: + super().set(not super().get()) + self._image = value + + @_override + def get(self) -> _Image: + return self._image + + class Base64Photo(CanvasBased, VariableControlled): def __init__(self, master: _Misc, theme_key: str = "CTkLabel", width: float = 0, height: float = 0, - variable: _StringVar | None = None, + variable: _StringVar | ImageVariable | None = None, fg_color: _Color | None = None, hover_color: _Color | None = None, bg_color: _Color | None = None, @@ -32,8 +48,10 @@ def __init__(self, def dynamic_renderer(self, canvas: CanvasBased) -> None: canvas.clear("d") w, h, hc, vc, limit = canvas.meta() - if base64 := self._variable.get(): - self._image = _PhotoImage(_base64_decode_image(base64).resize((w, h))) + if image := self._variable.get(): + if isinstance(image, str): + image = _base64_decode_image(image) + self._image = _PhotoImage(image.resize((w, h))) canvas.collect("d0", canvas.create_image(hc, vc, image=self._image)) @_override From 60bd72da8f44d3b61f2ad6eea6962bf1f30a8cac Mon Sep 17 00:00:00 2001 From: ATATC Date: Sun, 14 Jul 2024 21:45:41 +0800 Subject: [PATCH 2/2] Renamed `Base64Photo` to `Photo` as it has become more general. (#278) --- leads_gui/photo.py | 2 +- leads_vec/cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/leads_gui/photo.py b/leads_gui/photo.py index 820c3258..354be716 100644 --- a/leads_gui/photo.py +++ b/leads_gui/photo.py @@ -25,7 +25,7 @@ def get(self) -> _Image: return self._image -class Base64Photo(CanvasBased, VariableControlled): +class Photo(CanvasBased, VariableControlled): def __init__(self, master: _Misc, theme_key: str = "CTkLabel", diff --git a/leads_vec/cli.py b/leads_vec/cli.py index 61ac8982..32919e60 100644 --- a/leads_vec/cli.py +++ b/leads_vec/cli.py @@ -14,7 +14,7 @@ from leads_audio import DIRECTION_INDICATOR_ON, DIRECTION_INDICATOR_OFF, WARNING, CONFIRM from leads_gui import RuntimeData, Window, GForceVar, FrequencyGenerator, Left, Color, Right, ContextManager, \ Typography, Speedometer, ProxyCanvas, SpeedTrendMeter, GForceMeter, Stopwatch, Hazard, initialize, Battery, Brake, \ - ESC, Satellite, Motor, Speed, Base64Photo, Light + ESC, Satellite, Motor, Speed, Photo, Light from leads_vec.__version__ import __version__ @@ -88,7 +88,7 @@ def render(manager: ContextManager) -> None: font=("Arial", cfg.font_size_small - 4)) ) if has_device(REAR_VIEW_CAMERA): - m1_widgets += (Base64Photo(root, theme_key="CTkButton", variable=var_rear_view_base64),) + m1_widgets += (Photo(root, theme_key="CTkButton", variable=var_rear_view_base64),) manager["m1"] = ProxyCanvas(root, "CTkButton", *m1_widgets).lock_ratio(cfg.m_ratio) manager["m2"] = Speedometer(root, variable=var_speed).lock_ratio(cfg.m_ratio) manager["m3"] = ProxyCanvas(root, "CTkButton",