简体   繁体   中英

Tkinter press a button to launch an animation .py file

Original question:

I have a Tkinter button which upon pressing will execute a script.py file.

#-*- coding: utf-8 -*-
from Tkinter import *
master = Tk()
def callback():
    execfile("script.py")
b = Button(master, text="OK", command=callback)
b.pack()
mainloop()

The script.py is a 2D animation which will open a window for animation.

"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

x = np.arange(0, 2*np.pi, 0.01)        # x-array
line, = ax.plot(x, np.sin(x))

def animate(i):
    line.set_ydata(np.sin(x+i/10.0))  # update the data
    return line,

#Init only required for blitting to give a clean slate.
def init():
    line.set_ydata(np.ma.array(x, mask=True))
    return line,
ani = animation.FuncAnimation(fig, animate, np.arange(1,200),init_func=init,interval=25, blit=True)
plt.show()

When I run the Tkinter code above and pressed button to call the animation, animation will only show first frame. In other words, animation will not be played. But if script.py is run from command line, animation plays correctly. The question is, how to make animation plays when run from the Tkinter code?

I was not able to reproduce the behavior you encounter, execution breaks in init.

File "script.py", line 19, in init
  line.set_ydata(np.ma.array(x, mask=True))

However, you could redesign your application to rely on more conventional import to execute python code from another file. You can alter your script.py this way

#script.py
def script():
    #previous script.py content

if __name__ == '__main__':
    script()

This way, if you run the file, you match the __name__ == '__main__' clause and your file will run on its own. When you import it, the script function will be defined but not executed. From your tkinter program, you just need to

import script

def callback():
    script.script()

I unexpectedly found a way to get around this animation problem, and thought that it's worth writing down.

If in the script.py file, I return a global variable from the execfile function, the animation callback by the TK button will now play correctly.

from Tkinter import *
master = Tk()
def callback():
    variables= {} #add a variable with witch execfile can return
    execfile("simple_anime.py",    variables)
b = Button(master, text="OK", command=callback)
b.pack()
mainloop()

This way it will work. And, I just realized, this is what TigerhawkT3 mentioned in his answer. I looked into subprocess but I'm still not sure how to use it in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM