Python Tkinter:为用户选择的点设置颜色

Python Tkinter:为用户选择的点设置颜色,python,tkinter,Python,Tkinter,我有一个图像保存为image.png。我的任务的工作流程如下: 在Tkinter中加载图像以及图像下方的“选择两点”按钮 用户在图像的两点上用鼠标左键单击两次 当他选择第一个点时,该特定点会高亮显示(比如红色或任何颜色);然后他选择第二个点,第二个点也会突出显示 两点的(x,y)坐标存储在全局变量中,稍后将使用 一旦用户选择了两个点,就会出现第二个“完成!”按钮。单击此按钮时,GUI关闭。注意:我希望这两点保持突出显示,直到用户单击关闭按钮,这样他/她就知道自己单击的位置 我设法解决了所有步骤,

我有一个图像保存为
image.png
。我的任务的工作流程如下:

  • 在Tkinter中加载图像以及图像下方的“选择两点”按钮
  • 用户在图像的两点上用鼠标左键单击两次
  • 当他选择第一个点时,该特定点会高亮显示(比如红色或任何颜色);然后他选择第二个点,第二个点也会突出显示
  • 两点的(x,y)坐标存储在全局变量中,稍后将使用
  • 一旦用户选择了两个点,就会出现第二个“完成!”按钮。单击此按钮时,GUI关闭。注意:我希望这两点保持突出显示,直到用户单击关闭按钮,这样他/她就知道自己单击的位置
  • 我设法解决了所有步骤,除了步骤3。我发现的最相似的事情是用
    画布创建一个矩形。创建矩形(x,y,x+1,y+1,fill=“red”)
    ,但首先我喜欢一个圆,其次我不想将
    画布链接到我的
    标签

    任何帮助都将不胜感激:D

    以下是我目前的代码:

    root = Tk()  # create a window
    
    frame = Frame(root)  # define upper frame
    middleframe = Frame(root)  # define middle frame
    exitFrame = Frame(root)  # define exit frame
    frame.pack()  # pack the frame
    middleframe.pack()  # pack the subframe
    exitFrame.pack(side = 'bottom')  # pack the exit frame
    
    # function that closes the GUI
    def close_window(): 
        root.destroy()
    
    # load the image
    img = PhotoImage(file="image.png")  # save the image
    panel = Label(frame, image=img)  # display the image as a label
    panel.grid(row=0, column=0)  # pack the image
    
    # make the user select some points
    global x_Coordinates  # initialize empty list for storing x-axis coordinates
    global y_Coordinates  # initialize empty list for storing y-axis coordinates
    x_Coordinates = []
    y_Coordinates = []
    
    clicks = 0
    def countClicks():
      global clicks # this will use the variable to count
      clicks = clicks + 1  # increment "clicks"
      if clicks == 2: # if the user has selected 2 points, add a button that closes the window
          exit_button = Button(exitFrame, state = "normal", text = "Done!", command = close_window)  # link the closing function to the button
          exit_button.grid(row=2, column=0, pady=5)  # set button position with "grid"        
    pass
    
    def selectPoints():  # function called when user clicks the button "select two points"
        panel.bind("<Button 1>", saveCoordinates)  #  link the function to the left-mouse-click event
        exit_button = Button (exitFrame, state = "disabled", text = "Done!", command = close_window)  # link closing function to the button
        exit_button.grid(row=2, column=0, pady=5)  # set button position with "grid"
        button_select_points.config(state = "disabled") # switch button state to "disabled"
    
    def saveCoordinates(event): # function called when left-mouse-button is clicked   
        x_coordinate = event.x  # save x and y coordinates selected by the user
        y_coordinate = event.y
        x_Coordinates.append(x_coordinate)  # append to external list
        y_Coordinates.append(y_coordinate)  # append to external list
        countClicks()  # invoke function "countClicks"
    
    button_select_points = Button(middleframe, text = "select two points", command = selectPoints)  # insert button and link it to "selectPoints"
    button_select_points.grid(row=1, column=0, pady=5)  # set button position with "grid"
    
    root.mainloop()  # keep the GUI open
    
    root=Tk()#创建一个窗口
    框架=框架(根)#定义上部框架
    中间帧=帧(根)#定义中间帧
    exitFrame=帧(根)#定义退出帧
    frame.pack()#打包框架
    middleframe.pack()#打包子帧
    exitFrame.pack(side='bottom')#打包出口框架
    #关闭GUI的函数
    def关闭_窗口():
    root.destroy()
    #加载图像
    img=PhotoImage(file=“image.png”)#保存图像
    面板=标签(框架,图像=img)#将图像显示为标签
    panel.grid(行=0,列=0)#打包图像
    #让用户选择一些点
    全局x#坐标#初始化空列表以存储x轴坐标
    全局y#坐标#初始化空列表以存储y轴坐标
    x_坐标=[]
    y_坐标=[]
    点击次数=0
    def countClicks():
    全局单击#这将使用变量进行计数
    点击次数=点击次数+1#增加“点击次数”
    如果单击==2:#如果用户选择了2个点,则添加一个关闭窗口的按钮
    exit_button=按钮(exitFrame,state=“normal”,text=“Done!”,command=close_window)#将关闭功能链接到按钮
    退出按钮网格(行=2,列=0,pady=5)#用“网格”设置按钮位置
    通过
    def selectPoints():#当用户单击“选择两点”按钮时调用的函数
    panel.bind(“,saveCoordinates)#将函数链接到鼠标左键单击事件
    退出按钮=按钮(exitFrame,state=“disabled”,text=“Done!”,command=关闭窗口)#将关闭功能链接到按钮
    退出按钮网格(行=2,列=0,pady=5)#用“网格”设置按钮位置
    按钮选择点配置(state=“disabled”)#将按钮状态切换为“disabled”
    def saveCoordinates(事件):#单击鼠标左键时调用的函数
    x_坐标=事件。x#保存用户选择的x和y坐标
    y_坐标=事件。y
    x_坐标。附加(x_坐标)#附加到外部列表
    y_坐标。追加(y_坐标)#追加到外部列表
    countClicks()#调用函数“countClicks”
    按钮\选择\点=按钮(中间框,text=“选择两点”,command=selectPoints)\插入按钮并将其链接到“selectPoints”
    按钮\选择\点。网格(行=1,列=0,pady=5)\用“网格”设置按钮位置
    root.mainloop()#保持GUI打开
    
    除非您想做的不仅仅是设置几个像素,否则您可能更容易使用
    画布
    小部件,它有一些更高级的绘图原语(例如矩形和椭圆形)

    (这里有一些关于小部件的相当全面的Tkinter文档。)

    下面是您的代码,并对其进行了修改(加上一些其他代码,通过遵循指导原则和删除一些我认为不必要和/或太多余的内容,使其更具可读性)

    它定义了一个名为
    create\u circle()
    的新辅助函数,以简化更通用的
    Canvas
    小部件的
    create\u oval()
    方法的调用。现在在
    saveCoordinates()
    函数中调用该函数(该函数现在绑定到新的
    Canvas
    对象的
    事件,而不是您正在使用的
    标签)

    从tkinter导入*
    root=Tk()#创建一个窗口
    框架=框架(根)#定义上部框架
    中间帧=帧(根)#定义中间帧
    exitFrame=帧(根)#定义退出帧
    frame.pack()#打包框架
    middleframe.pack()#打包子帧
    exitFrame.pack(side='bottom')#打包出口框架
    #关闭GUI的函数
    def关闭_窗口():
    root.destroy()
    img=PhotoImage(file=“myimage.png”)#加载图像
    画布=画布(框架,宽度=img.width(),高度=img.height(),边框宽度=0)
    canvas.grid(行=0,列=0)
    canvas.create_image(0,0,image=img,anchor=NW)
    #让用户选择一些点
    x_坐标=[]存储x轴坐标的列表
    y_坐标=[]存储y轴坐标的列表
    点击次数=0
    def创建_圆(画布,x,y,半径,**kwargs):
    返回画布。创建椭圆(x半径,y半径,x+半径,y+半径,**kwargs)
    def countClicks():
    全球点击
    单击次数+=1
    #如果用户选择了2个点,则添加一个关闭窗口的按钮
    如果单击==2:
    #将关闭功能链接到按钮
    退出按钮=按钮(exitFrame,state=“normal”,text=“Done!”,
    命令=关闭(窗口)
    退出按钮网格(行=2,列=0,pady=5)#用“网格”设置按钮位置
    def selectPoints():#当用户单击“选择两点”按钮时调用的函数
    #将函数链接到鼠标左键单击事件
    canvas.bind(“,saveCoordinates)
    #李
    
    from tkinter import *
    
    root = Tk()  # create a window
    
    frame = Frame(root)  # define upper frame
    middleframe = Frame(root)  # define middle frame
    exitFrame = Frame(root)  # define exit frame
    frame.pack()  # pack the frame
    middleframe.pack()  # pack the subframe
    exitFrame.pack(side='bottom')  # pack the exit frame
    
    # function that closes the GUI
    def close_window():
        root.destroy()
    
    img = PhotoImage(file="myimage.png")  # load the image
    canvas = Canvas(frame, width=img.width(), height=img.height(), borderwidth=0)
    canvas.grid(row=0, column=0)
    canvas.create_image(0, 0, image=img, anchor=NW)
    
    # make the user select some points
    x_Coordinates = []  # list for storing x-axis coordinates
    y_Coordinates = []  # list for storing y-axis coordinates
    clicks = 0
    
    def create_circle(canvas, x, y, radius, **kwargs):
        return canvas.create_oval(x-radius, y-radius, x+radius, y+radius, **kwargs)
    
    def countClicks():
        global clicks
    
        clicks += 1
        # if the user has selected 2 points, add a button that closes the window
        if clicks == 2:
            # link the closing function to the button
            exit_button = Button(exitFrame, state="normal", text="Done!",
                                 command=close_window)
            exit_button.grid(row=2, column=0, pady=5)  # set button position with "grid"
    
    def selectPoints():  # function called when user clicks the button "select two points"
        # link the function to the left-mouse-click event
        canvas.bind("<Button 1>", saveCoordinates)
        # link closing function to the button
        exit_button = Button (exitFrame, state="disabled", text="Done!",
                              command=close_window)
        exit_button.grid(row=2, column=0, pady=5)  # set button position with "grid"
        button_select_points.config(state="disabled") # switch button state to "disabled"
    
    def saveCoordinates(event): # function called when left-mouse-button is clicked
        x_coordinate = event.x  # save x and y coordinates selected by the user
        y_coordinate = event.y
        x_Coordinates.append(x_coordinate)
        y_Coordinates.append(y_coordinate)
        # Display a small dot showing position of point.
        create_circle(canvas, x_coordinate, y_coordinate, radius=3, fill='red')
        countClicks()
    
    # insert button and link it to "selectPoints"
    button_select_points = Button(middleframe, text="select two points",
                                  command=selectPoints)
    button_select_points.grid(row=1, column=0, pady=5)
    
    root.mainloop()  # keep the GUI open
    
    img.put(("red",), to=(event.x, event.y))
    
    img.put(("red",), to=(event.x-1, event.y-1, event.x+1, event.y+1))