import pickle
from tkinter import Frame, Canvas, NW
from typing import Any, Dict, Optional
from PIL import Image, ImageTk
from pathlib import Path
[docs]
class MyPlot(Frame):
"""
A custom plot widget that displays images in a Frame with blinking capability.
This class creates a plot display widget that can show images and supports blinking
between two different images. It uses a Canvas widget for image display and can
load additional data from pickle files for blinking functionality.
Attributes:
width (int): Width of the plot display area
height (int): Height of the plot display area
image (Optional[PhotoImage]): The current image being displayed
image1 (Optional[PhotoImage]): First image for blinking
image2 (Optional[PhotoImage]): Second image for blinking
canvas (Canvas): The Canvas widget for image display
string1 (Optional[Any]): Additional data loaded from first pickle file
string2 (Optional[Any]): Additional data loaded from second pickle file
"""
[docs]
def __init__(
self,
parent: Any,
row: int,
column: int,
width: int,
height: int,
path_default: Path,
columnspan: int = 2,
rowspan: int = 1,
**kwargs: Dict[str, Any]
) -> None:
"""
Initialize the MyPlot widget.
Args:
parent: The parent widget
row: Row position in the parent's grid
column: Column position in the parent's grid
width: Width of the plot display area
height: Height of the plot display area
path_default: Base path for finding the test image file
columnspan: Number of columns the widget should span
rowspan: Number of rows the widget should span
**kwargs: Additional keyword arguments passed to the Frame widget
"""
super().__init__(
parent,
bg="#FFFFFF",
width=width,
height=height,
highlightbackground="black",
highlightthickness=1,
padx=5,
pady=2,
**kwargs,
)
# Set up the test image path
path_test_image = str(Path.joinpath(path_default, "GUIBRUSHR", "Files", "Test", "test.png"))
# Store dimensions
self.width = width
self.height = height
# Initialize image attributes
self.image = None
self.image1 = None
self.image2 = None
# Create and configure the canvas
self.canvas = Canvas(self, width=self.width, height=self.height)
self.canvas.pack()
# Initialize additional data attributes
self.string1 = None
self.string2 = None
# Display the initial test image
self.insert_image_gui(path_test_image)
# Grid the frame into the parent
self.grid(row=row, column=column, columnspan=columnspan, rowspan=rowspan)
[docs]
def blink_preparation(
self,
path1: str,
path2: str,
path_pkl1: str,
path_pkl2: str
) -> None:
"""
Prepare images and data for blinking functionality.
Args:
path1: Path to the first image file
path2: Path to the second image file
path_pkl1: Path to the first pickle file containing additional data
path_pkl2: Path to the second pickle file containing additional data
"""
# Load and resize images
self.image1 = ImageTk.PhotoImage(
Image.open(path1).resize((int(self.width), int(self.height)))
)
self.image2 = ImageTk.PhotoImage(
Image.open(path2).resize((int(self.width), int(self.height)))
)
# Load additional data from pickle files
with open(path_pkl1, "rb") as fo:
self.string1 = pickle.load(fo)
with open(path_pkl2, "rb") as fo:
self.string2 = pickle.load(fo)
[docs]
def insert_image_gui(self, path_image: str, blink: Optional[str] = None) -> None:
"""
Display an image in the canvas.
Args:
path_image: Path to the image file to display
blink: If "1" or "2", use the corresponding blink image instead of loading a new one
"""
if blink == "1":
image = self.image1
elif blink == "2":
image = self.image2
else:
self.image = ImageTk.PhotoImage(
Image.open(path_image).resize((int(self.width), int(self.height)))
)
image = self.image
self.canvas.create_image(0, 0, anchor=NW, image=image)