如何通过单击 canvas 小部件来协调数组值和 tkinter canvas 的变化?

How can I coordinate the change in array value and tkinter canvas by clicking on canvas widget?

我开发了一个十六进制游戏接口,它获取一个二维数组(白色单元格的值为 1,黑色单元格的值为 2,

0 为空单元格)和屏幕上第一个六边形的坐标作为输入,并根据第一个

绘制十六进制的 table

点.

我想触发鼠标左键单击的动作,将单元格的值更改为 1 或 2(这意味着播放

点击单元格中的白色或黑色宝石)。当我单击单元格并打印数组时,游戏中单击单元格的值

棋盘变了,但点击的六边形颜色没有变

除非点击触发器中的图形发生变化,否则这是正确的代码。

from tkinter import *
class gui:
    """
    This class is built to let the user have a better interaction with
    game.
    inputs =>
    canvas = Canvas(root)
    board = board is the array of gamestate class which shows the game board.
    start_points = This entry indicates an array of points which is the top
    left coordinate of item of the graphical interface.
    """
    def __init__(self, root, start_points, board):
        self.canvas = Canvas(root, width=900, height=768)
        self.board = board
        self.start = [start_points[0], start_points[1], start_points[2],
                       start_points[3], start_points[4], start_points[5]]
        self.temp = []
        for i in self.start:
            self.temp.append(i)
        self.initial_offset = 20   # Offset for each row and first item
        self.hex_x = 40            # Offset for each hexagon in each row
        self.hex_y = 40            # Offset from top of screen
        self.hex_board = []
        self.array_to_hex(self.board)
        self.bind()
        self.canvas.pack(anchor='nw')

    def hexagon(self, points, color):
        """
        Creates a hexagon by getting a list of points and their assigned colors
        according to the game board
        """
        if color is 0:
             hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                             points[3], points[4], points[5],
                                        fill='#fe8b03', outline='black', width=2)
        elif color is 1:
             hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                             points[3], points[4], points[5],
                                        fill='white', outline='black', width=2)
        else:
             hx = self.canvas.create_polygon(points[0], points[1], points[2],
                                             points[3], points[4], points[5],
                                        fill='#3e3f3a', outline='black', width=2)
        return hx

     def genrow(self, points, colors):
         """
         By getting a list of points as the starting point of each row and a list of
         colors as the dedicated color for each item in row, it generates a row of
         hexagons by calling hexagon functions multiple times.
         """
         row = []
         temp_array = []
         for i in range(len(colors)):
             for point in points:
                 temp_points_x = point[0] + self.hex_x * i
             temp_points_y = point[1]
             temp_array.append([temp_points_x, temp_points_y])
         if colors[i] is 0:
             hx = self.hexagon(temp_array, 0)
         elif colors[i] is 1:
             hx = self.hexagon(temp_array, 1)
         else:
             hx = self.hexagon(temp_array, 2)
         row.append(hx)
         temp_array = []
     return row

 def array_to_hex(self, array):
     """
     Simply gets the gameboard and generates the hexagons by their dedicated colors.
     """
     for i in range(len(array)):
         for point in self.temp:
             point[0] += self.hex_x
             point[1] += self.hex_y
         for point in self.temp:
             point[0] -= self.initial_offset
         row = self.genrow(self.temp, self.board[i])
         self.temp.clear()
         for k in self.start:
             self.temp.append(k)
         self.hex_board.append(row)

     def bind(self):
         """
         Binding triggers for the actions defined in the class.
         """
         self.canvas.bind('<Motion>', self.mouse_motion)
         self.canvas.bind('<1>', self.mouse_click)

     def mouse_motion(self, event):
         """
         Simply implements a hovering action for each item
         """
         if self.canvas.find_withtag(CURRENT):
             current_color = self.canvas.itemcget(CURRENT, 'fill')
             self.canvas.itemconfig(CURRENT, fill="cyan")
             self.canvas.update_idletasks()
             self.canvas.after(150)
             self.canvas.itemconfig(CURRENT, fill=current_color)

     def mouse_click(self, event):
         """
         This function changes the color of item (depending on the player turns)
         to assigned color
         """
         x, y = event.x, event.y
         idd = self.canvas.find_overlapping(x, y, x, y)
         idd = list(idd)
         if len(idd) is not 0:
             p = idd[0]
             index = [[ix, iy] for ix,
             row in enumerate(self.hex_board) for iy,
             i in enumerate(row) if i == p][0]
             self.board[index[0]][index[1]] = 1
             for i in self.board:
                 print(i)
             print('\n')

 row_item_offset = 40
 x_offset = 20
 y_offset = 40
 points1 = [[25, 10], [45, 25], [45, 50], [25, 65], [5, 50], [5, 25]]
 test_array = [[1, 0, 0, 0, 0, 0],
               [0, 0, 2, 0, 0, 0],
               [1, 1, 1, 2, 1, 2],
               [0, 0, 0, 2, 0, 2],
               [0, 1, 0, 0, 1, 2],
               [0, 0, 0, 2, 0, 0]]
 root = Tk()
 hexagons = gui(root, points1, test_array)
 root.mainloop()

我有点想刷新整个项目或使用 forget 方法删除整个小部件并重新打包,但我

不知道如何实现。 我想我需要修改 mouse_click_trigger 方法。 谁能对示例代码提出任何建议? 谢谢。

我真的希望这就是您要找的:

from tkinter import *
root = Tk()
root.geometry("600x600-400+50")
root.title("Game")

class App:
    def __init__(self, master):
        self.master = master

        self.rbvar = IntVar()

        self.stonerb = Radiobutton(self.master, text="Stone",
                                   variable=self.rbvar, value=1, command=self.figurefunc)
        self.stonerb.pack()

        self.blackrb = Radiobutton(self.master, text="Black",
                                   variable=self.rbvar, value=2, command=self.figurefunc)
        self.blackrb.pack()

        self.board = Canvas(self.master, bg='#b35900', width=500, height=500)
        self.board.pack()

        self.figure = self.board.create_polygon(0,0, 0,0, 0,0, 0,0, 0,0, 0,0)

        self.stoneCoords = 60,200, 100,200, 120,230, 100,260, 60,260, 40,230
        self.blackCoords = 440,200, 400,200, 380,230, 400,260, 440,260, 460,230

    def figurefunc(self):
        if self.rbvar.get() == 1:
            self.board.coords(self.figure, self.stoneCoords)
            self.board.itemconfig(self.figure, fill='#f2f2f2')
        else:
            self.board.coords(self.figure, self.blackCoords)
            self.board.itemconfig(self.figure, fill='black')


myapp = App(root)

呸!