HPInc / HP-Digital-Microfluidics

HP Digital Microfluidics Software Platform and Libraries
MIT License
2 stars 0 forks source link

Redo monitor in tkinter #253

Open EvanKirshenbaum opened 5 months ago

EvanKirshenbaum commented 5 months ago

This is a specific approach to #52.

Yesterday, @cumbiem asked ChatGPT

“Write me a gui in python using the tkinter library that allows the user to place one or more circles on a 20 x 20 grid with white background and black cell lines that will snap the circle to the center of each grid cell with left mouse click, however, if an adjacent cell to one that already has a circle in it is clicked, move the closest circle to this cell instead of making a new circle. Delete an existing circle if the right mouse button is clicked.”

and it spit back

import tkinter as tk

class Grid:
    def __init__(self, master):
        self.master = master
        self.canvas = tk.Canvas(self.master, width=400, height=400, bg="white")
        self.canvas.pack()
        self.cells = []
        self.circles = []

        for i in range(20):
            for j in range(20):
                x1, y1 = i * 20, j * 20
                x2, y2 = x1 + 20, y1 + 20
                cell = self.canvas.create_rectangle(x1, y1, x2, y2, outline="black")
                self.cells.append(cell)

        self.canvas.bind("<Button-1>", self.add_circle)
        self.canvas.bind("<Button-3>", self.delete_circle)

    def add_circle(self, event):
        x, y = event.x, event.y
        cell_size = 20

        row, col = y // cell_size, x // cell_size
        x_center = (col * cell_size) + cell_size // 2
        y_center = (row * cell_size) + cell_size // 2

        for circle in self.circles:
            circle_x, circle_y = self.canvas.coords(circle)[0] + cell_size // 2, self.canvas.coords(circle)[1] + cell_size // 2
            if abs(circle_x - x_center) <= cell_size and abs(circle_y - y_center) <= cell_size:
                closest_circle = circle
                break
        else:
            closest_circle = None

        if closest_circle is None:
            circle = self.canvas.create_oval(x_center - 10, y_center - 10, x_center + 10, y_center + 10, fill="red")
            self.circles.append(circle)
        else:
            self.canvas.coords(closest_circle, x_center - 10, y_center - 10, x_center + 10, y_center + 10)

    def delete_circle(self, event):
        x, y = event.x, event.y
        cell_size = 20

        for circle in self.circles:
            circle_x, circle_y = self.canvas.coords(circle)[0] + cell_size // 2, self.canvas.coords(circle)[1] + cell_size // 2
            if abs(circle_x - x) <= cell_size and abs(circle_y - y) <= cell_size:
                self.circles.remove(circle)
                self.canvas.delete(circle)
                break

root = tk.Tk()
root.title("Grid of Circles")
grid = Grid(root)
root.mainloop()

which is surprisingly good.

I started playing with the tool, and it looks as though it might be able to give me examples of ways to do the various things that are necessary to port monitor.py to tkinter.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Feb 17, 2023 at 2:35 PM PST.