C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

Canvasでon_hoverイベント3

こちらの続きです。
Canvasでon_hoverイベント2 - C#ATIA

textfieldに"x,y,直径"を入力するとそれに該当する円を描くように
修正します。
TextField | Flet
描かれた円上でホバーすると色が変わります。

# python using-flet
import flet as ft
import flet.canvas as cv
import math

def main(page: ft.Page) -> None:
    canvasWidth = 600
    canvasHeight = 600

    stroke_paint = ft.Paint(stroke_width=5, style=ft.PaintingStyle.STROKE)
    line_paint = ft.Paint(stroke_width=1, style=ft.PaintingStyle.STROKE)
    fill_paint = ft.Paint(style=ft.PaintingStyle.FILL, color=ft.colors.BLACK)

    def on_hover(e: ft.DragStartEvent) -> None:
        x=e.local_x-(canvasWidth*0.5)
        y=(e.local_y-(canvasHeight*0.5))*-1

        shapes = [s for s in canvas.shapes if isinstance(s, cv.Circle)]
        change_color(shapes, e.local_x, e.local_y)

        pos.value = f"{x},{y}"
        pos.update()

    def on_exit(e: ft.DragStartEvent) -> None:
        pos.value = "-"
        pos.update()

    def is_hover(shape, x, y) -> None:
        return  math.sqrt(
            (shape.x - x)*(shape.x - x) + (shape.y - y)*(shape.y - y)
        ) < shape.radius

    def change_color(shapes, x, y) -> None:
        for shape in reversed(shapes):
            if is_hover(shape, x, y):
                shape.paint.color = ft.colors.RED
            elif shape.paint.color != ft.colors.BLACK:
                shape.paint.color = ft.colors.BLACK
            shape.update()

    def create_circle(e: ft.DragStartEvent) -> None:
        canvas.shapes = canvas.shapes[:3]
        canvas.update()

        lst = e.control.value.split("\n")
        for txt in lst:
            info = txt.split(",")
            if len(info) < 3: continue
            if not all([is_float(v) for v in info]): continue

            canvas.shapes.append(
                cv.Circle(
                    x=float(info[0])+(canvasWidth*0.5),
                    y=(float(info[1])*-1)+(canvasHeight*0.5),
                    radius=float(info[2])*0.5,
                    paint=fill_paint,
                )
            )
        canvas.update()

    def is_float(value) -> bool:
        try:
            float(value)
            return True
        except:
            return False

    gd = ft.GestureDetector(
        hover_interval=10,
        on_hover=on_hover,
        on_exit=on_exit,
    )

    canvas = cv.Canvas(
        [
            cv.Rect(0,0,canvasWidth,canvasHeight,10,stroke_paint),
            cv.Line(canvasWidth*0.5,0,canvasWidth*0.5,canvasHeight,line_paint),
            cv.Line(0,canvasHeight*0.5,canvasWidth,canvasHeight*0.5,line_paint),
        ],
        width=canvasWidth,
        height=canvasHeight,
        content=gd,
    )

    pos = ft.Text(
        "-",
        size=30,
    )

    page.theme_mode = ft.ThemeMode.LIGHT
    page.add(
        ft.Row(
            controls=[
                canvas,
                ft.Column(
                    controls=[
                        ft.Container(
                            bgcolor=ft.colors.BLUE_100,
                            alignment=ft.alignment.top_center,
                            width=200,
                            content=pos
                        ),
                        ft.TextField(
                            multiline=True,
                            max_lines=10,
                            on_change=create_circle,
                        ),
                    ]
                ),
            ]
        ),
    )

ft.app(target = main)

固定サイクルのみのNCデータであれば、簡単なビューアーが作れるかも。