示例#1
0
 def change_image(self, image_path: str) -> None:
     try:
         self.image.load_image(image_path)
     except ValueError:
         self.clear_image()
         PUBLISHER.queue_message("ImageLoadingError")
     self.update_image()
示例#2
0
 def image_selection(self, image_path: str) -> None:
     try:
         self.validator.validate_resolution()
         self.image.scaled_resolution = int(self.state.resolution)
     except ValueError:
         return
     self.image.overlay.clear()
     PUBLISHER.queue_message("ImageChangeRequest", image_path=image_path)
示例#3
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("FramerateChangeRequest", function=self.set_framerate),
         Subscriber("ResolutionChangeRequest",
                    function=self.set_resolution),
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#4
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("ImageChangeRequest", function=self.change_image),
         Subscriber("ImageUpdateRequest", function=self.update_image),
         Subscriber("ImagePixelReplaceRequest",
                    function=self.replace_pixels),
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#5
0
 def save_command(self) -> None:
     filename = filedialog.asksaveasfilename(
         title="Save Image",
         defaultextension="png",
         filetypes=[("PNG", ".png"), ("JPG", ".jpg"), ("JPEG", ".jpeg")],
     )
     if not filename:
         return
     PUBLISHER.queue_message("ImageSaveRequest", image_path=filename)
示例#6
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("ImageSelectionRequest", function=self.image_selection),
         Subscriber("ImageResetRequest", function=self.image_reset),
         Subscriber("ImageSaveRequest", function=self.image_save),
         Subscriber("ImageLoadingError", function=self.image_loading_error),
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#7
0
 def maze_solve(self) -> None:
     try:
         self.validator.validate_image()
         self.validator.validate_framerate()
     except ValueError:
         return
     self.image.reset_result()
     PUBLISHER.queue_process_message("Maze", start=True, state=self.state)
     self.state.working = True
示例#8
0
 def maze_reset(self) -> None:
     PUBLISHER.queue_process_message(
         "Maze",
         reset=True,
         wait_for_response=True,
         message_timeout=0.2,
         response_timeout=0.2,
     )
     self.state.working = False
示例#9
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("MazeSolveRequest", function=self.maze_solve),
         Subscriber("MazeStopRequest", function=self.maze_stop),
         Subscriber("MazeResumeRequest", function=self.maze_resume),
         Subscriber("MazeCancelRequest", function=self.maze_reset),
         Subscriber("MazeSolveDone", function=self.maze_solve_done),
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#10
0
 def _image_clicked(self, event: tk.Event) -> None:
     if not self.image.loaded:
         return
     x: int = event.x  # type: ignore[attr-defined]
     y: int = event.y  # type: ignore[attr-defined]
     scaled_width, scaled_height = self._get_scaled_size()
     height, width, _ = self.image.pixels.shape
     real_x = int(x * (width / scaled_width))
     real_y = int(y * (height / scaled_height))
     PUBLISHER.queue_message("ImageClicked", x=real_x, y=real_y)
示例#11
0
 def validate_framerate(self) -> None:
     try:
         integer_framerate = int(self.framerate)
     except ValueError:
         self.show_framerate_error()
         PUBLISHER.queue_message("FramerateResetRequest")
         raise ValueError(f"Invalid Framerate: {self.framerate}")
     if not isInRange(integer_framerate, MIN_FRAMERATE, MAX_FRAMERATE):
         PUBLISHER.queue_message("FramerateResetRequest")
         self.show_framerate_error()
         raise ValueError(f"Invalid Framerate: {self.framerate}")
示例#12
0
 def validate_resolution(self) -> None:
     try:
         integer_resolution = int(self.resolution)
     except ValueError:
         PUBLISHER.queue_message("ResolutionResetRequest")
         self.show_resolution_error()
         raise ValueError(f"Invalid Resolution: {self.resolution}")
     if not isInRange(integer_resolution, MIN_RESOLUTION, MAX_RESOLUTION):
         PUBLISHER.queue_message("ResolutionResetRequest")
         self.show_resolution_error()
         raise ValueError(f"Invalid Resolution: {self.resolution}")
示例#13
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("PointChangeRequest", function=self.set_status),
         Subscriber("ImageClicked", function=self.set_point),
         Subscriber(
             "ImageChangeRequest",
             function=lambda *args, **kwargs: self.reset_points(),
         ),
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#14
0
 def set_point(self, x: int, y: int) -> None:
     if self.state.working or not self.state.image.loaded:
         return
     if self.status == PointStatus.START:
         self.start_point = Point(x, y)
     elif self.status == PointStatus.END:
         self.end_point = Point(x, y)
     if self.status != PointStatus.NONE:
         self.image.reset_result()
         self.image.overlay.clear()
         self._set_start_point()
         self._set_end_point()
         PUBLISHER.queue_message("ImageUpdateRequest")
     self.status = PointStatus.NONE
示例#15
0
 def select_image(self) -> None:
     filename = filedialog.askopenfilename(title="Select an Image")
     if not filename:
         return
     PUBLISHER.queue_message("MazeCancelRequest")
     PUBLISHER.queue_message("ImageSelectionRequest", image_path=filename)
示例#16
0
 def solve_command(self) -> None:
     PUBLISHER.queue_message("MazeSolveRequest")
示例#17
0
 def stop_command(self) -> None:
     PUBLISHER.queue_message("MazeStopRequest")
示例#18
0
 def maze_resume(self) -> None:
     PUBLISHER.queue_process_message("Maze", resume=True)
示例#19
0
 def maze_stop(self) -> None:
     PUBLISHER.queue_process_message("Maze", stop=True)
示例#20
0
 def resume_command(self) -> None:
     PUBLISHER.queue_message("MazeResumeRequest")
示例#21
0
 def _setup_subscribers(self) -> None:
     subscribers = [
         Subscriber("FramerateResetRequest", function=self.reset)
     ]
     for subscriber in subscribers:
         PUBLISHER.register_subscriber(subscriber)
示例#22
0
 def image_reset(self) -> None:
     self.image.reset_result()
     PUBLISHER.queue_message("ImageUpdateRequest")
示例#23
0
 def start_point_command(self) -> None:
     PUBLISHER.queue_message("PointChangeRequest", kind="start")
示例#24
0
 def end_point_command(self) -> None:
     PUBLISHER.queue_message("PointChangeRequest", kind="end")
示例#25
0
 def _entry_changed(self, *_: Any) -> None:
     resolution = self.string_var.get()
     PUBLISHER.queue_message("ResolutionChangeRequest",
                             resolution=resolution)
示例#26
0
 def _periodic_refresh(self) -> None:
     PUBLISHER.send_messages()
     self.root.after(1000 // 60, self._periodic_refresh)
示例#27
0
 def cancel_command(self) -> None:
     PUBLISHER.queue_message("MazeCancelRequest")
示例#28
0
from mazesolver.controller import ApplicationController
from mazesolver.gui import ApplicationGui
from mazesolver.solver import Solver
from mazesolver.pubsub import PUBLISHER, ProcessSubscriber
from mazesolver.image import MazeImage

if __name__ == "__main__":
    image = MazeImage()
    controller = ApplicationController(image)
    gui = ApplicationGui(image)
    solver = Solver()
    subscriber = ProcessSubscriber("Maze", worker=solver)
    PUBLISHER.register_subscriber(subscriber)
    gui.start()
示例#29
0
 def _entry_changed(self, *_: Any) -> None:
     framerate = self.string_var.get()
     PUBLISHER.queue_message("FramerateChangeRequest", framerate=framerate)