I have a program that allows you to move an image if you click on the image than click on the square you want it to go. I have two frames, both with the same images but I want to restrict image movement to only the frames that they are currently in.
I have tried to do things like if self.squares[0, dict_rank_pieces or self.white_images] in self.squares[1, pos]
but that doesn't work
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)
self.frame2 = tk.Frame(self)
self.pack()
self.square_color = None
self.squares = {}
self.ranks = string.ascii_lowercase
self.white_images = {} # stores images of pieces
self.black_images = {}
self.white_pieces = ["image1", "image2", "image3", "image4", "image5"]
self.black_pieces = ["image1", "image2", "image3", "image4", "image5"]
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.piece_color = 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)]
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:
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):
for i, frame in enumerate((self.frame1, self.frame2)):
pos = self.ranks[x] + str(y + 1)
b = tk.Button(frame, bg=self.square_color, activebackground="lawn green")
b.grid(row=x, column=y, sticky="nsew")
b.config(command=lambda key=b: self.select_piece(key))
self.squares[i, pos] = b
def import_pieces(self): # opens and stores images of pieces and prepares the pieces for the game for both sides
path = os.path.join(os.path.dirname(__file__), "white") # stores white pieces images into dicts
w_dirs = os.listdir(path)
for file in w_dirs:
img = Image.open(path + "/" + file)
img = img.resize((80, 80), Image.Resampling.LANCZOS)
img = ImageTk.PhotoImage(image=img)
self.white_images.setdefault(file, img)
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')
root = tk.Tk()
root.geometry("800x800")
board = Board(root, 5, 5)
board.import_pieces()
board.set_pieces()
board.mainloop()
As said in my comment of your other question, you can use the key of self.squares
, i.e. the values of self.sq1
and self.sq2
which are of the format in (frame_index, position), to determine whether the selected squares are in the same frame:
def select_piece(self, button):
if self.buttons_pressed == 0:
...
elif self.buttons_pressed == 1:
...
# do nothing if same square is selected
# or they are not in same frame
if (self.sq2 == self.sq1) or (self.sq2[0] != self.sq1[0]):
self.button_pressed = 0
return
...