Я пытаюсь создать двоичный лабиринт s1, где 1 представляет препятствие, а ноль - отсутствие препятствия. Я представляю лабиринт с помощью сетки прямоугольников. При щелчке по прямоугольникам я хочу изменить соответствующее значение в матрице s1. Если его значение равно 1, оно должно измениться на 0 и наоборот. Проблема заключается в том, когда я координаты меняются, и я не могу преобразовать координаты прямоугольника в значения индекса s1.Проверьте функцию "clickrectangle"
import tkinter as tk
import numpy
import math
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
global size,s1,items,z,rows,columns
rows = 35
columns=35
scale=1
items=[]
size=40
z=[]
self.item = 0; self.previous = (0, 0)
self.canvas = tk.Canvas(self, width=1000, height=1000, background="bisque")
self.xsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
self.ysb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.ysb.set, xscrollcommand=self.xsb.set)
self.canvas.configure(scrollregion = (0,0,rows*size*1.05,columns*size*1.05))
self.xsb.grid(row=1, column=0, sticky="ew")
self.ysb.grid(row=0, column=1, sticky="ns")
self.canvas.grid(row=0, column=0, sticky="nsew")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
#Plot some rectangles
l=rows
b=columns
s1= numpy.array([[0]*l]*b)
s1[0]=[1]*l
s1[-1]=[1]*l
for i in range(l):
s1[i][0]=1
s1[i][-1]=1
for i in range(0,size*rows,size):
for j in range(0,size*columns,size):
f=s1[int(i/size)][int(j/size)]
if(f==0):
c="black"
elif(f==1):
c="#CAC6C5"
r = self.canvas.create_rectangle(i,j,i+size,j+size,fill=c,outline='grey')
# This is what enables using the mouse:
self.canvas.bind("<ButtonPress-1>", self.move_start)
self.canvas.bind("<B1-Motion>", self.move_move)
self.canvas.bind("<ButtonPress-1>", self.clickrectangle)
self.canvas.bind("<Motion>", self.move_move2)
#linux scroll
self.canvas.bind("<Button-4>", self.zoomerP)
self.canvas.bind("<Button-5>", self.zoomerM)
#windows scroll
self.canvas.bind("<MouseWheel>",self.zoomer)
# Hack to make zoom work on Windows
root.bind_all("<MouseWheel>",self.zoomer)
def clickrectangle(self,event):
xc = self.canvas.canvasx(event.x);
yc = self.canvas.canvasy(event.y)
r = event.widget.find_closest(xc, yc)
x=int(math.floor(xc/size))
y=int(math.floor(yc/size))
print(x,y)
if(self.canvas.itemcget(r,"fill")=="black"):
self.canvas.itemconfig( r,fill="#CAC6C5")
s1[x][y]=1
elif(self.canvas.itemcget(r,"fill")=="#CAC6C5"):
self.canvas.itemconfig( r,fill="black")
s1[x][y]=0
#move
def move_start(self, event):
self.canvas.scan_mark(event.x, event.y)
def move_move(self, event):
self.canvas.scan_dragto(event.x, event.y, gain=1)
#move
def pressed2(self, event):
global pressed
pressed = not pressed
self.canvas.scan_mark(event.x, event.y)
def move_move2(self, event):
if pressed:
self.canvas.scan_dragto(event.x, event.y, gain=1)
#windows zoom
def zoomer(self,event):
global scale,z
xc = self.canvas.canvasx(event.x)
yc = self.canvas.canvasy(event.y)
if (event.delta > 0):
self.canvas.scale("all", xc, yc, 1.1, 1.1)
z.append((xc,yc,1.1))
elif (event.delta < 0):
self.canvas.scale("all", xc,yc, 0.9, 0.9)
z.append((xc,yc,0.9))
#linux zoom
def zoomerP(self,event):
xc = self.canvas.canvasx(event.x)
yc = self.canvas.canvasy(event.y)
self.canvas.scale("all", xc, yc, 1.1, 1.1)
def zoomerM(self,event):
xc = self.canvas.canvasx(event.x)
yc = self.canvas.canvasy(event.y)
self.canvas.scale("all", xc, yc, 0.9, 0.9)
if __name__ == "__main__":
root = tk.Tk()
E=Example(root)
E.pack( expand=True)
#f.pack(fill="both", expand=True)
root.mainloop()