我在使用VB6永远被困后开始学习Python。为了帮助自己学习Tkinter的一些gui,我正在制作一个简单的老虎机。为了给车轮设置动画,我有一个~300x2000的图像,其中包含我打算用作条带的所有图片。现在约有6张照片。我只是一次显示部分图像(滚轮)以使其旋转。无论如何,我遇到了代码的一部分问题,我到了图像的末尾,需要从图像的末尾过渡到开始(轮子旋转,所以开始是底部和结束是顶部)。
出于某种原因,我无法正确裁剪和显示图像,即使我认为我的脚本在逻辑上有意义。我的代码发布在下面。您可以在300x2000左右的分辨率左右制作图像,以便用它来查看我遇到的问题。我的代码开始在我希望它显示的区域之外打印(在showsize变量之外),我无法找出原因。
非常感谢任何有关此问题的帮助。似乎作物没有足够短的缩短图像,但我发现的所有信息都让我觉得我的剧本应该工作得很好。我试图注释我的代码来解释发生了什么。
from Tkinter import *
from PIL import Image, ImageTk
def main():
root = Tk()
root.title = ("Slot Machine")
canvas = Canvas(root, width=1500, height=800)
canvas.pack()
im = Image.open("colors.png")
wheelw = im.size[0] #width of source image
wheelh = im.size[1] #height of source image
showsize = 400 #amount of source image to show at a time - part of 'wheel' you can see
speed = 3 #spin speed of wheel
bx1 = 250 #Box 1 x - where the box will appear on the canvas
by = 250 #box 1 y
numberofspins = 100 #spin a few times through before stopping
cycle_period = 0 #amount of pause between each frame
for spintimes in range(1,numberofspins):
for y in range(wheelh,showsize,-speed): #spin to end of image, from bottom to top
cropped = im.crop((0, y-showsize, wheelw, y)) #crop which part of wheel is seen
tk_im = ImageTk.PhotoImage(cropped)
canvas.create_image(bx1, by, image=tk_im) #display image
canvas.update() # This refreshes the drawing on the canvas.
canvas.after(cycle_period) # This makes execution pause
for y in range (speed,showsize,speed): #add 2nd image to make spin loop
cropped1 = im.crop((0, 0, wheelw, showsize-y)) #img crop 1
cropped2 = im.crop((0, wheelh - y, wheelw, wheelh)) #img crop 2
tk_im1 = tk_im2 = None
tk_im1 = ImageTk.PhotoImage(cropped1)
tk_im2 = ImageTk.PhotoImage(cropped2)
#canvas.delete(ALL)
canvas.create_image(bx1, by, image=tk_im2) ###THIS IS WHERE THE PROBLEM IS..
canvas.create_image(bx1, by + y, image=tk_im1) ###PROBLEM
#For some reason these 2 lines are overdrawing where they should be. as y increases, the cropped img size should decrease, but doesn't
canvas.update() # This refreshes the drawing on the canvas
canvas.after(cycle_period) # This makes execution pause
root.mainloop()
if __name__ == '__main__':
main()
答案 0 :(得分:0)
如果不在每个周期重新创建图像,它会更简单,更快更顺畅。这是我使用canvas.move()
的解决方案。请注意,我将canvas.create_image
调用移到了for循环之外。我还将代码放在一个类中并添加了一个“旋转”按钮,并添加了一些东西以使其退出而没有错误。
from Tkinter import *
from PIL import Image, ImageTk
import sys
class SlotMachine():
def __init__(self):
root = Tk()
root.title = ("Slot Machine")
self.canvas = Canvas(root, width=1200, height=800)
self.canvas.grid(column=0,row=0)
button = Button(root, text="Spin!", width=20, command = self.spin)
button.grid(column=0,row=1)
self.alive = True
root.protocol("WM_DELETE_WINDOW", self.die)
root.mainloop()
def spin(self):
im = Image.open("colors.png")
wheelw = im.size[0] #width of source image
wheelh = im.size[1] #height of source image
showsize = 400 # amount of source image to show at a time -
# part of 'wheel' you can see
speed = 3 #spin speed of wheel
bx1 = 250 #Box 1 x - where the box will appear on the canvas
by = 250 #box 1 y
numberofspins = 100 #spin a few times through before stopping
cycle_period = 3 #amount of pause between each frame
tk_im1 = ImageTk.PhotoImage(im)
tk_im2 = ImageTk.PhotoImage(im)
im1id = self.canvas.create_image(bx1, by + showsize, image=tk_im1)
im2id = self.canvas.create_image(bx1, by + showsize + wheelh,
image=tk_im2)
for spintimes in range(1,numberofspins):
for y in range(wheelh,0,-speed):
if self.alive:
self.canvas.move(im1id, 0, -speed)
self.canvas.move(im2id, 0, -speed)
self.canvas.update()
self.canvas.after(cycle_period)
else:
sys.exit()
self.canvas.move(im1id, 0, wheelh)
self.canvas.move(im2id, 0, wheelh)
def die(self):
self.alive = False
if __name__ == '__main__':
mySlotMachine = SlotMachine()
这会将车轮的一部分放在箱子外面,但你可以把你的老虎机纹理放在上面。