使用Tkinter正确实例化类

时间:2014-04-08 12:51:09

标签: python tkinter

我的目标是每次用户按下换档按钮时加载一个新的“箭头”图像。我想,我可以为箭头创建一个类,这样我就可以为它们创建一个新实例,其中每个实例都有自己的坐标,依此类推。但显然我做错了。我试图为实例创建一个列表,以便我可以迭代它,然后在每个实例中使用moveArrow方法。我只有5个条目,因为我当时想要限制5个箭头。我希望这段代码不会给你带眼镜或类似的东西:P我是一个新手,我很抱歉,如果代码非常糟糕或者如何处理我的问题的方法。谢谢你的帮助:))

#!/usr/bin/python

from Tkinter import *
from PIL import ImageTk, Image


class frameApp(Frame):
        def __init__(self, master=None):
                Frame.__init__(self, master, height = 400, width = 400)
                self.charImg = ImageTk.PhotoImage(Image.open("Archer.gif"))
                self.arrowImage = ImageTk.PhotoImage(Image.open("arrow.gif"))
                self.charLabel = Label(self, image = self.charImg) #Loading character label
                self.charLabel.pack()
                self.arrow = Label(self, image = self.arrowImage)
                self.arrow.pack()
                self.shift = False
                self.down = False
                self.right = False
                self.left = False
                self.up = False
                self.x_coord = 200
                self.y_coord = 200
                self.pack_propagate(0)
                self.pack()
                self.arrowList = ["Inst1", "Inst2", "Inst3", "Inst4", "Inst5"]
                self.counter = -1
        def moveableImage(self):
                self.charLabel.place(y=self.y_coord, x=self.x_coord)
        def createArrow(self):
                self.arrowList[counter] = arrow()
        def moveArrow(self):
                for arrowList in self.arrowList:
                        arrowList.moveArrow

        def keyPressed(self, event):
                if event.keysym == 'Down':
                        self.down = True
                elif event.keysym == 'Right':
                        self.right = True
                elif event.keysym == 'Left':
                        self.left = True
                elif event.keysym == 'Up':
                        self.up = True
                elif event.keysym == 'Shift_L':
                        self.shift = True
        def keyReleased(self, event):
                if event.keysym == 'Down':
                        self.down = False
                elif event.keysym == 'Right':
                        self.right = False
                elif event.keysym == 'Left':
                        self.left = False
                elif event.keysym == 'Up':
                        self.up = False
                elif event.keysym == 'Shift_L':
                        self.shift = False
        def task(self):
                if self.down and self.y_coord < 360:
                        self.y_coord = self.y_coord + 10
                elif self.right and self.x_coord < 370:
                        self.x_coord = self.x_coord + 10
                elif self.left and self.x_coord > 10:
                        self.x_coord = self.x_coord - 10
                elif self.up and 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()

class arrow(object):
        def __init__(self):
                self.x_coordArrow = app.x_coord
                self.y_coordArrow = app.y_coord
        def moveArrow(self):
                self.x_coordArrow = self.x_coordArrow + 20

root = Tk()
root.title("Frametitel")
app = frameApp(master=root)
root.bind_all('<Key>', app.keyPressed)
root.bind_all('<KeyRelease>', app.keyReleased)
root.after(20, app.task)
app.mainloop()

1 个答案:

答案 0 :(得分:1)

您有几种方法可以解决此问题。创建一个新类来调用arrow()的多个实例可能是要走的路。

我为你拥有的应用程序窗口创建一个类,但是除去应该在Arrow类中的所有不必要的东西。然后,使Arrow类成为Tkinter小部件的子类,如Frame,并使其处理其方法。

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

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()