Python 使用Tkinter正确实例化类

Python 使用Tkinter正确实例化类,python,tkinter,Python,Tkinter,我的目标是每次用户按下shift按钮时加载一个新的“箭头”图像。我想,我可以为箭头创建一个类,这样我就可以为它们创建一个新的实例,每个实例都有自己的坐标等等。但很明显我做错了。我试图为实例创建一个列表,这样我就可以对其进行迭代,然后在每个实例中使用moveArrow方法。我只得到了5个条目,因为我希望一次最多有5个箭头。我希望这段代码不会给你带来眼癌或类似的问题:P我是一个新手,如果代码真的很糟糕,或者是如何处理我的问题,我很抱歉。谢谢你的帮助:) #/usr/bin/python 从Tkint

我的目标是每次用户按下shift按钮时加载一个新的“箭头”图像。我想,我可以为箭头创建一个类,这样我就可以为它们创建一个新的实例,每个实例都有自己的坐标等等。但很明显我做错了。我试图为实例创建一个列表,这样我就可以对其进行迭代,然后在每个实例中使用moveArrow方法。我只得到了5个条目,因为我希望一次最多有5个箭头。我希望这段代码不会给你带来眼癌或类似的问题:P我是一个新手,如果代码真的很糟糕,或者是如何处理我的问题,我很抱歉。谢谢你的帮助:)

#/usr/bin/python
从Tkinter进口*
从PIL导入ImageTk,图像
类frameApp(框架):
def uuu init uuu(self,master=None):
帧。u_初始__;(自,主,高度=400,宽度=400)
self.charImg=ImageTk.PhotoImage(Image.open(“Archer.gif”))
self.arrowImage=ImageTk.PhotoImage(Image.open(“arrow.gif”))
self.charLabel=Label(self,image=self.charImg)#加载字符标签
self.charLabel.pack()
self.arrow=标签(self,image=self.arrow图像)
self.arrow.pack()
self.shift=False
self.down=False
self.right=False
self.left=False
self.up=False
self.x_坐标=200
self.y_坐标=200
self.pack_传播(0)
self.pack()
self.arrowList=[“Inst1”、“Inst2”、“Inst3”、“Inst4”、“Inst5”]
self.counter=-1
def可移动映像(自身):
self.charLabel.place(y=self.y\u坐标,x=self.x\u坐标)
def createArrow(自身):
self.arrowList[计数器]=箭头()
def移动箭头(自身):
对于self.arrowList中的arrowList:
arrowList.moveArrow
按def键(自身,事件):
如果event.keysym==“向下”:
self.down=True
elif event.keysym=='Right':
self.right=True
elif event.keysym==‘Left’:
self.left=True
elif event.keysym==“向上”:
self.up=True
elif event.keysym=='Shift_L':
self.shift=True
def钥匙释放(自身、事件):
如果event.keysym==“向下”:
self.down=False
elif event.keysym=='Right':
self.right=False
elif event.keysym==‘Left’:
self.left=False
elif event.keysym==“向上”:
self.up=False
elif event.keysym=='Shift_L':
self.shift=False
def任务(自我):
如果self.down和self.y_坐标<360:
self.y_坐标=self.y_坐标+10
elif self.right和self.x_coord<370:
self.x_坐标=self.x_坐标+10
elif self.left和self.x_coord>10:
self.x_坐标=self.x_坐标-10
elif self.up和self.y_coord>10:
self.y_-coord=self.y_-coord-10
elif self.shift:
self.counter+=1
self.createArrow()
root.after(20,self.task)
root.after(20,self.moveArrow)
self.moveableImage()
类箭头(对象):
定义初始化(自):
self.x_坐标箭头=app.x_坐标
self.y_坐标箭头=app.y_坐标
def移动箭头(自身):
self.x_coordArrow=self.x_coordArrow+20
root=Tk()
根标题(“框架”)
app=frameApp(master=root)
root.bind_all(“”,应用程序按键)
root.bind_all(“”,应用程序密钥已发布)
root.after(20,应用程序任务)
app.mainloop()

您有几个选项来处理此问题。创建一个新类来调用
arrow()
的多个实例可能是一种方法

我会为应用程序窗口创建一个类,您已经有了这个类,但是从中去掉了所有不必要的东西,这些东西应该在Arrow类中。然后,使Arrow类成为Tkinter小部件的子类,如
框架
,并让它处理其方法

这是一个非常简化的版本:

from Tkinter import *
from random import randint

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master, height=400, width=400)
        self.master = master
        self.master.bind('<Shift_L>', self.createArrow)

    def createArrow(self, event):
        #this is the only arrow method in this class. It waits for the Shift event,
        #then makes a new instance of Arrow and calls Arrow's method to get it moving
        self.arrow = Arrow(self)
        self.arrow.moveArrow(self.arrow, randint(0,400), randint(0,400))

class Arrow(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)    #This makes the frame,
        Label(self, text='===>').pack() #and puts a Label (the graphic) inside it

    def moveArrow(self, arrow, xCoord, yCoord):
        #the move arrow method - arguments are the arrow instance and the x,y coords
        arrow.place_forget()            #un-place the instance
        arrow.place(x=xCoord, y=yCoord) #replace with new x,y
        self.after(500, lambda: self.moveArrow(arrow, xCoord+1, yCoord)) #repeat, changing x

root = Tk()
app = App(root).pack()
root.mainloop()
从Tkinter导入*
从随机导入randint
类应用程序(框架):
def uuu init uuu(self,master=None):
帧。u_初始__;(自,主,高度=400,宽度=400)
self.master=master
self.master.bind(“”,self.createArrow)
def createArrow(自身,事件):
#这是该类中唯一的arrow方法。它等待移位事件,
#然后创建一个新的Arrow实例并调用Arrow的方法使其移动
self.arrow=箭头(self)
self.arrow.moveArrow(self.arrow,randint(0400),randint(0400))
类箭头(框架):
定义初始(自我,主):
帧。uuu init(self,master)#这使得帧,
Label(self,text='==>')。pack()#并在其中放置一个标签(图形)
def移动箭头(self、arrow、xCoord、yCoord):
#move arrow方法参数是arrow实例和x,y坐标
arrow.place_-forget()#取消放置实例
箭头。放置(x=xCoord,y=yCoord)#替换为新的x,y
self.after(500,lambda:self.moveArrow(arrow,xCoord+1,yCoord))#重复,更改x
root=Tk()
app=app(root).pack()
root.mainloop()

为什么moveArrow方法没有给出最大递归错误?您正在moveArrow()方法中调用self.moveArrow(arrow,xCoord+15,yCoord)。你不应该有一个在任何阶段都没有中断的无休止的递归吗?看看我对你关于这个问题的另一个回答。你是
from Tkinter import *
from random import randint

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master, height=400, width=400)
        self.master = master
        self.master.bind('<Shift_L>', self.createArrow)

    def createArrow(self, event):
        #this is the only arrow method in this class. It waits for the Shift event,
        #then makes a new instance of Arrow and calls Arrow's method to get it moving
        self.arrow = Arrow(self)
        self.arrow.moveArrow(self.arrow, randint(0,400), randint(0,400))

class Arrow(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)    #This makes the frame,
        Label(self, text='===>').pack() #and puts a Label (the graphic) inside it

    def moveArrow(self, arrow, xCoord, yCoord):
        #the move arrow method - arguments are the arrow instance and the x,y coords
        arrow.place_forget()            #un-place the instance
        arrow.place(x=xCoord, y=yCoord) #replace with new x,y
        self.after(500, lambda: self.moveArrow(arrow, xCoord+1, yCoord)) #repeat, changing x

root = Tk()
app = App(root).pack()
root.mainloop()