Python 是否有其他方法可以将单击的互动程序与间隙交换?
如何在间隙平铺和单击的平铺之间进行交换? 我下面的代码显示了单击的内容,但只要我想交换这两个内容,就会出现一个错误 最终目标是创建一个滑动益智游戏,但首先我只想交换两个瓷砖,然后我将设置一个条件,即只能单击间隙瓷砖周围的瓷砖 对不起,如果这是一个愚蠢的问题,我已经坐了2天与此代码,并开始看到双!xDPython 是否有其他方法可以将单击的互动程序与间隙交换?,python,tkinter,Python,Tkinter,如何在间隙平铺和单击的平铺之间进行交换? 我下面的代码显示了单击的内容,但只要我想交换这两个内容,就会出现一个错误 最终目标是创建一个滑动益智游戏,但首先我只想交换两个瓷砖,然后我将设置一个条件,即只能单击间隙瓷砖周围的瓷砖 对不起,如果这是一个愚蠢的问题,我已经坐了2天与此代码,并开始看到双!xD from tkinter import* from tkinter import filedialog from PIL import Image, ImageTk import random im
from tkinter import*
from tkinter import filedialog
from PIL import Image, ImageTk
import random
import os
#=========================================================================================================================================================================
class Tiles(Label):
def __init__(self,grid):
self.tiles = []
self.grid = grid
self.gap = None
def add(self,tile):
self.tiles.append(tile)
def getTile(self, *pos):
for tile in self.tiles:
if tile.pos == pos:
return tile
def getTileAroundGap(self):
gRow,gCol = self.gap.pos
return self.getTile(gRow,gCol-1),self.getTile(gRow-1,gCol),self.getTile(gRow,gCol+1),self.getTile(gRow+1,gCol)
def changeGap(self,tile):
gPos = self.gap.pos
self.gap.pos = tile.pos
tile.pos = gPos
def slide(self, pos):
#left,top,down,right = self.getTileAroundGap()
self.changeGap(self.getTile(pos))
def setGap(self, index):
self.gap = self.tiles[index]
self.show()
def shuffle(self):
random.shuffle(self.tiles)
i=0
for row in range(self.grid):
for col in range(self.grid):
self.tiles[i].pos = (row,col)
i +=1
def show(self):
for tile in self.tiles:
if self.gap != tile:
tile.show()
#=========================================================================================================================================================================
class Tile(Label):
def __init__(self, parent, image, pos):
Label.__init__(self, parent, image=image)
self.bind("<Button-1>", self.click)
self.image = image
self.pos = pos
self.curPos = pos
def click(self, event):
print("clicked on", self.pos)
Board.slideIt(Board,self.pos)
def show(self):
self.grid(row = self.pos[0], column = self.pos[1])
#=========================================================================================================================================================================
class Board(Frame):
MAX_SIZE = 450
def __init__(self,parent,image,grid,*args,**kwargs):
Frame.__init__(self,parent,*args,**kwargs)
self.parent = parent
self.grid = grid
self.image = self.openImage(image)
self.tileSize = self.image.size[0]/self.grid
self.tiles = self.createTiles()
self.tiles.shuffle()
self.tiles.show()
def openImage(self,image):
image = Image.open(image)
if (image.size[0] > 450 or image.size[1] > 450):
image = image.resize((self.MAX_SIZE,self.MAX_SIZE),Image.ANTIALIAS)
if image.size[0] != image.size[1]:
image = image.crop((0,0,image.size[0],image.size[0]))
return image
def slideIt(self, pos):
self.tiles.slide(pos)
def createTiles(self):
tiles = Tiles(self.grid)
for row in range(self.grid):
for col in range(self.grid):
x0 = col*self.tileSize
y0 = row*self.tileSize
x1 = x0+self.tileSize
y1 = y0+self.tileSize
tileImage = ImageTk.PhotoImage(self.image.crop((x0,y0,x1,y1)))
tile = Tile(self,tileImage,(row,col))
tiles.add(tile)
tiles.show()
tiles.setGap(-1)
return tiles
# def importCSV():
# global csvFilePath
# csvFilePath = filedialog.askopenfilename()
#=========================================================================================================================================================================
class Main():
def __init__(self,parent):
self.parent = parent
self.image = StringVar()
self.createWidgets()
def createWidgets(self):
self.mainFrame = Frame(self.parent)
Label(self.mainFrame, text = 'AI Puzzle Game', font= ("Times New Roman",40)).pack(padx = 10, pady = 10)
frame = Frame(self.mainFrame)
Label(frame, text = 'Image').grid(sticky = W)
Entry(frame,textvariable = self.image).grid(row=0, column=1, padx = 30, pady = 30)
Button(frame, text = "Browse", command = self.browse).grid(row=0, column=2, padx = 30, pady = 30)
frame.pack(padx = 30, pady = 30)
Button(self.mainFrame, text = "Start", command = self.start,font= ("Arial",15,"bold")).pack(padx = 30, pady = 30)
self.mainFrame.pack()
self.board = Frame(self.parent)
self.winFrame = Frame(self.parent)
def start(self):
image = self.image.get()
if os.path.exists(image):
self.board = Board(self.parent,image,3)
self.mainFrame.pack_forget()
self.board.pack()
def browse(self):
self.image.set(filedialog.askopenfilename(title = "Select Image", filetype = (("JPG File","*.jpg"),("PNG File","*.png"))))
if __name__ == "__main__":
root = Tk()
Main(root)
root.mainloop()
我很难理解这是如何工作的,但有一个问题;从
tile()
创建每个磁贴时,不会保存对父(板)的引用。然后在方法中单击()
调用类Board()
,而不是实例=self.parent
class Tile(Label):
def __init__(self, parent, image, pos):
Label.__init__(self, parent, image=image)
self.bind("<Button-1>", self.click)
self.parent = parent # Save reference to parent
self.image = image
self.pos = pos
self.curPos = pos
def click(self, event):
self.parent.slideIt(self.pos) # Call method on parent
def show(self):
self.grid(row = self.pos[0], column = self.pos[1])
此代码不会为我生成任何错误 嘿,伙计,谢谢你的回复!它的工作原理是,当我点击“开始”时,它会创建一个电路板。然后一个图像被裁剪并分为9个平铺(在createTiles中),其中一个设置为间隙平铺。它将在板上显示瓷砖。我尝试了你的解决方案,但还是遇到了同样的错误。我得到了大致的想法,但是
Tiles()
类中有很多方法,我没有费心去理解它们。但是我对代码的修改肯定比我想象的要多,所以我在我的整个示例中都发布了。我已经将其缩短为不必每次运行时都打开文件等。现在它从电路板错误更改为:AttributeError:'NoneType'对象没有属性'pos',非常感谢!那么我的问题到底是什么呢?这都在我的答案中;调用类而不是实例,然后提供具有错误参数的方法。
class Tile(Label):
def __init__(self, parent, image, pos):
Label.__init__(self, parent, image=image)
self.bind("<Button-1>", self.click)
self.parent = parent # Save reference to parent
self.image = image
self.pos = pos
self.curPos = pos
def click(self, event):
self.parent.slideIt(self.pos) # Call method on parent
def show(self):
self.grid(row = self.pos[0], column = self.pos[1])
from tkinter import*
from tkinter import filedialog
from PIL import Image, ImageTk
import random
import os
#=========================================================================================================================================================================
class Tiles(Label):
def __init__(self,grid):
self.tiles = []
self.grid = grid
self.gap = None
def add(self,tile):
self.tiles.append(tile)
def getTile(self, pos):
for tile in self.tiles:
if tile.pos == pos:
return tile
def getTileAroundGap(self):
gRow,gCol = self.gap.pos
return self.getTile(gRow,gCol-1),self.getTile(gRow-1,gCol),self.getTile(gRow,gCol+1),self.getTile(gRow+1,gCol)
def changeGap(self, tile):
gPos = self.gap.pos
self.gap.pos = tile.pos
tile.pos = gPos
def slide(self, pos):
#left,top,down,right = self.getTileAroundGap()
self.changeGap(self.getTile(pos))
def setGap(self, index):
self.gap = self.tiles[index]
self.show()
def shuffle(self):
random.shuffle(self.tiles)
i=0
for row in range(self.grid):
for col in range(self.grid):
self.tiles[i].pos = (row,col)
i +=1
def show(self):
for tile in self.tiles:
if self.gap != tile:
tile.show()
#=========================================================================================================================================================================
class Tile(Label):
def __init__(self, parent, image, pos):
Label.__init__(self, parent, image=image)
self.bind("<Button-1>", self.click)
self.parent = parent # Save reference to parent
self.image = image
self.pos = pos
self.curPos = pos
def click(self, event):
self.parent.slideIt(self.pos) # Call method on parent
def show(self):
self.grid(row = self.pos[0], column = self.pos[1])
#=========================================================================================================================================================================
class Board(Frame):
MAX_SIZE = 450
def __init__(self, parent, image, grid, *args, **kwargs):
Frame.__init__(self,parent,*args,**kwargs)
self.parent = parent
self.grid = grid
self.image = self.openImage(image)
self.tileSize = self.image.size[0]/self.grid
self.tiles = self.createTiles()
self.tiles.shuffle()
self.tiles.show()
def openImage(self,image):
image = Image.open(image)
if (image.size[0] > 450 or image.size[1] > 450):
image = image.resize((self.MAX_SIZE,self.MAX_SIZE),Image.ANTIALIAS)
if image.size[0] != image.size[1]:
image = image.crop((0,0,image.size[0],image.size[0]))
return image
def slideIt(self, pos):
self.tiles.slide(pos)
def createTiles(self):
tiles = Tiles(self.grid)
for row in range(self.grid):
for col in range(self.grid):
x0 = col*self.tileSize
y0 = row*self.tileSize
x1 = x0+self.tileSize
y1 = y0+self.tileSize
tileImage = ImageTk.PhotoImage(self.image.crop((x0,y0,x1,y1)))
tile = Tile(self, tileImage, (row,col))
tiles.add(tile)
tiles.show()
tiles.setGap(-1)
return tiles
if __name__ == "__main__": # Reduced the code a bit...
root = Tk()
image = 'images/idle.png'
board = Board(root, image, 3)
board.pack()
root.mainloop()