Tkinter Image Viewer Method

2019-08-02 11:29发布

I am an atmospheric scientist, struggling through python (2.7 using PIL and Tkinter) in an attempt to create a simple image viewer that will display some of the forecast products we eventually produce. I would like to implement a start, stop, forward, backward, and loop button. The loop button and its associated callback currently work correctly. The loop method is credited to Glenn Pepper (found an open-source project via google). Here is the code:

from Tkinter import *
from PIL import Image, ImageTk
import tkMessageBox
import tkFileDialog

#............................Button Callbacks.............................#

root = Tk()
root.title("WxViewer")
root.geometry("1500x820+0+0")

def loop():
    StaticFrame = []
    for i in range(0,2):

        fileName="filename"+str(i)+".gif"
        StaticFrame+=[PhotoImage(file=fileName)]
    def animation(currentframe):

        def change_image():
            displayFrame.create_image(0,0,anchor=NW,
                        image=StaticFrame[currentframe], tag='Animate')
            # Delete the current picture if one exist
        displayFrame.delete('Animate')
        try:
            change_image()
        except IndexError:
                    # When you get to the end of the list of images -
                    #it simply resets itself back to zero and then we start again
            currentframe = 0
            change_image()
        displayFrame.update_idletasks() #Force redraw
        currentframe = currentframe + 1
            # Call loop again to keep the animation running in a continuous loop
        root.after(1000, animation, currentframe)
    # Start the animation loop just after the Tkinter loop begins
    root.after(10, animation, 0)


def back():
    print("click!")

def stop():
    print("click!")

def play():
    print("click!")

def forward():
    print("click!")
#..........................ToolFrame Creation............................#

toolFrame = Frame(root)
toolFrame.config(bg="gray40")
toolFrame.grid(column=0,row=0, sticky=(N,W,E,S) )
toolFrame.columnconfigure(0, weight = 1)
toolFrame.rowconfigure(0, weight = 1)
toolFrame.pack(pady = 0, padx = 10)


backButton = Button(toolFrame, text="Back", command = back)
backButton.pack(side = LEFT)

stopButton = Button(toolFrame, text = "Stop", command = stop)
stopButton.pack(side = LEFT)

playButton = Button(toolFrame, text = "Play", command = play)
playButton.pack(side = LEFT)

forwardButton = Button(toolFrame, text = "Forward", command = forward)
forwardButton.pack(side = LEFT)

loopButton = Button(toolFrame, text = "Loop", command = loop)
loopButton.pack(side = LEFT)

toolFrame.pack(side = TOP, fill=X)

#........................DisplayFrame Creation..........................#
displayFrame = Canvas(root, width=1024,height=768)
displayFrame.config(bg="white")
displayFrame.grid(column=0,row=0, sticky=(N,W,E,S) )
displayFrame.columnconfigure(0, weight = 1)
displayFrame.rowconfigure(0, weight = 1)
displayFrame.pack(pady = 5, padx = 10)
displayFrame.pack(side = LEFT, fill=BOTH)

#...............................Execution...............................#

root.mainloop()

It is rather straightforward. I have searched GitHub for projects, google, and stackoverflow but I am unsure how to make these five methods play nicely with each other. Could anyone share some pointers on how I could construct these other four methods so that they work appropriately? Thank you for your time!

1条回答
男人必须洒脱
2楼-- · 2019-08-02 11:59

I would replace the current loop function with something like the following (untested). The changes: add some global names to share data between functions; make change_image do everything needed to change an image, given that current_image is valid; except for the starting value, make current_image be always a valid image number when it is changed; factor forward() out of animate() (which is just repeated times forward calls).

n_images = 2
images = [PhotoImage(file="filename"+str(i)+".gif") for i in range(n_images)]
current_image = -1
def change_image():
    displayFrame.delete('Animate')
    displayFrame.create_image(0,0, anchor=NW,
                        image=StaticFrame[current_image], tag='Animate')
    displayFrame.update_idletasks() #Force redraw

callback = None
def animate():
    global callback
    forward()
    callback = root.after(1000, animate)

Here are three of the other functions.

def forward():
    global current_image
    current_image += 1
    if current_image >= n_images:
        current_image = 0
    change_image()

def back():
    global current_image
    current_image -= 1
    if current_image < 0:
        current_image = n_images-1
    change_image()

def stop():
    if callback is not None:
        root.after_cancel(callback)
查看更多
登录 后发表回答