左右框架内有按钮

问题描述 投票:0回答:1

我想在大型机中使用小部件创建两个相邻的框架,但我不知道如何使它们都可单击,而且我确信我的代码可以清理。如有任何帮助,我们将不胜感激!

我一开始只是用小部件制作一个框架,然后从那里开始,但我的主要问题是列表构造函数只能采用一个参数。我希望能够对两个框架使用 self.squares 变量,但我不确定如何做到这一点,因此我为第二个框架设置了另一个方形字典,但我认为这会使事情变得不必要的长。下面是我的代码。 #here 是我遇到最麻烦的地方。

class Board(tk.Frame):

    def __init__(self, parent, length, width):  # self=Frame, parent=root

        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.length = length
        self.width = width
        self.config(height=100 * self.length, width=100 * self.width)
        self.frame1 = tk.Frame()
        self.frame2 = tk.Frame()
        self.pack()

        self.squares = {}
        self.squares2 = {}
        self.ranks = string.ascii_lowercase
        self.buttons_pressed = 0
        self.turns = 0
        self.sq1 = None  # first square clicked
        self.sq2 = None
        self.sq1_button = None  # button associated with the square clicked
        self.sq2_button = None
        self.set_squares()

    def select_piece(self, button):
        if self.buttons_pressed == 0:
            self.sq1 = list(self.squares.keys())[list(self.squares.values()).index(button)] #here
            self.sq1_button = button
            self.buttons_pressed += 1

        elif self.buttons_pressed == 1:  # stores square and button of second square selected
            self.sq2 = list(self.squares.keys())[list(self.squares.values()).index(button)]
            self.sq2_button = button
            if self.sq2 == self.sq1:  # prevents self-destruction and allows the user to choose a new piece
                self.buttons_pressed = 0
                return
            if True:
                self.squares[self.sq2].config(image=self.sq1_button["image"])
                self.squares[self.sq2].image = self.sq1_button["image"]
                self.squares[self.sq1].config(image=self.white_images["blank.png"])  # clears sq1
                self.squares[self.sq1].image = self.white_images["blank.png"]
                self.buttons_pressed = 0
                return

    def set_squares(self):  # fills frame with buttons representing squares

        for x in range(5):
            for y in range(5):
                b = tk.Button(self.frame1, bg=self.square_color, activebackground="lawn green")
                b.grid(row=8 - x, column=y)
                b2 = tk.Button(self.frame2, bg=self.square_color, activebackground="lawn green")
                b2.grid(row=8 - x, column=y)
                pos = self.ranks[x] + str(y + 1)
                self.squares.setdefault(pos, b,)  # creates list of square positions
                self.squares2.setdefault(pos, b2)
                self.squares[pos].config(command=lambda key=self.squares[pos]: self.select_piece(key))
                self.squares2[pos].config(command=lambda key=self.squares2[pos]: self.select_piece(key))

    def set_pieces(self):  # places pieces in starting positions
        dict_rank1_pieces = {"a1": "dirt.png", "b1": "fire.png", "c1": "metal.png", "d1": "water.png", "e1": "wood.png"}

        for key in dict_rank1_pieces:  # inserts images into buttons
            starting_piece = dict_rank1_pieces[key]
            self.squares[key].config(image=self.white_images[starting_piece])
            self.squares[key].image = self.white_images[starting_piece]
            self.squares2[key].config(image=self.white_images[starting_piece])
            self.squares2[key].image = self.white_images[starting_piece]
            self.frame1.pack(side='left')
            self.frame2.pack(side='right')

        for rank in range(2, 6):  # fill rest with blank pieces
            for file in range(5):
                starting_piece = "blank.png"
                pos = self.ranks[file] + str(rank)
                self.squares[pos].config(image=self.white_images[starting_piece])
                self.squares[pos].image = self.white_images[starting_piece]
                self.squares2[pos].config(image=self.white_images[starting_piece])
                self.squares2[pos].image = self.white_images[starting_piece]


root = tk.Tk()
root.geometry("800x800")
board = Board(root, 5, 5)
board.import_pieces()
board.set_pieces()
board.mainloop()
python tkinter frames
1个回答
0
投票

如果您想对两个框架使用相同的

self.squares
,则需要使keys(目前它们类似于“a1”,“b1”等)唯一。建议之一是使用
(idx, key)
元组作为新的 key:

  • idx
    第一帧为 0,第二帧为 1
  • key
    是当前使用的key,即“a1”、“b1”等

以下是所需的修改:

class Board(tk.Frame):
    ...

    def set_squares(self):  # fills frame with buttons representing squares

        for x in range(5):
            for y in range(5):
                pos = self.ranks[x] + str(y + 1)
                for i, frame in enumerate((self.frame1, self.frame2)):
                    b = tk.Button(frame, bg=self.square_color, activebackground="lawn green")
                    b.grid(row=8 - x, column=y, sticky="nsew")
                    b.config(command=lambda key=b: self.select_piece(key))
                    # use tuple as key
                    self.squares[i,pos] = b

    def set_pieces(self):  # places pieces in starting positions
        dict_rank1_pieces = {"a1": "dirt.png", "b1": "fire.png", "c1": "metal.png", "d1": "water.png", "e1": "wood.png"}

        for key in dict_rank1_pieces:  # inserts images into buttons
            starting_piece = dict_rank1_pieces[key]
            # use tuple as key
            self.squares[0,key].config(image=self.white_images[starting_piece])
            self.squares[1,key].config(image=self.white_images[starting_piece])
            # suggest to move below two lines to __init__()
            self.frame1.pack(side='left')
            self.frame2.pack(side='right')

        for rank in range(2, 6):  # fill rest with blank pieces
            for file in range(5):
                starting_piece = "blank.png"
                pos = self.ranks[file] + str(rank)
                # use tuple as key
                self.squares[0,pos].config(image=self.white_images[starting_piece])
                self.squares[1,pos].config(image=self.white_images[starting_piece])

...

请注意,当前您已经创建了两个带有按钮的框架作为根窗口的子窗口,而不是

Board
。这真的是你想要的吗?


更新了

set_pieces()
,将图像放置在左帧的最左列和右帧的最右列:

def set_pieces(self):  # places pieces in starting positions
    dict_rank_pieces = {"a": "dirt.png", "b": "fire.png", "c": "metal.png", "d": "water.png", "e": "wood.png"}

    blank_piece = "blank.png"
    for rank in range(1, 6):  # fill rest with blank pieces
        for file in range(5):
            starting_piece = dict_rank_pieces[self.ranks[file]]
            pos = self.ranks[file] + str(rank)
            self.squares[0,pos].config(image=self.white_images[starting_piece if rank == 1 else blank_piece])
            self.squares[1,pos].config(image=self.white_images[starting_piece if rank == 5 else blank_piece])

    self.frame1.pack(side='left')
    self.frame2.pack(side='right')
© www.soinside.com 2019 - 2024. All rights reserved.