在Tkinter GUI内部更新matplotlib imshow

6

我正在尝试在Tkinter GUI中更新matplotlib imshow窗口中的数据,以下是我的代码示例:

#minimal example...

import matplotlib, sys
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import pylab as plt
from scipy import ndimage

if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk

root = Tk.Tk()
root.wm_title("minimal example")

image = plt.imread('test.jpg')
fig = plt.figure(figsize=(5,4))
im = plt.imshow(image) # later use a.set_data(new_data)
ax = plt.gca()
ax.set_xticklabels([]) 
ax.set_yticklabels([]) 

# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def rotate(*args):
    print 'rotate button press...'
    theta = 90
    rotated = ndimage.rotate(image, theta)
    im.set_data(rotated)
    root.update()

def quit(*args):
    print 'quit button press...'
    root.quit()     
    root.destroy() 

button_rotate = Tk.Button(master = root, text = 'Rotate', command = rotate)
button_quit = Tk.Button(master = root, text = 'Quit', command = quit)

button_quit.pack(side=Tk.LEFT)
button_rotate.pack()

Tk.mainloop()

如您所见,我使用imshow()加载图像,然后尝试使用set_data()更新图像数据,最后想要使用root.update()更新GUI的根窗口。当执行时,会执行打印“rotate button press…”行,但似乎其余部分没有执行。我需要以某种方式将图像句柄传递给旋转函数,或者返回旋转后的图像吗?


1
如果您正在嵌入其他应用程序,请勿导入 pyplot。否则会出现两个 GUI 主循环的竞争问题。 - tacaswell
@tcaswell 那很有道理,但如果我不使用 pylot,我该如何访问 imshow() - not link
请参见https://dev59.com/8GYq5IYBdhLWcg3wui0z#14261698。 - tacaswell
1个回答

3
< p > 画布需要重新绘制,尝试这样做: < /p >
def rotate(*args):
    print 'rotate button press...'
    theta = 90
    rotated = ndimage.rotate(image, theta)
    im.set_data(rotated)
    canvas.draw()

更新以保持旋转

请注意,这将image保存为root的属性。也许不是最好的方法,但对于这个示例来说可行。

root = Tk.Tk()
root.wm_title("minimal example")

root.image = plt.imread('test.jpg')
fig = plt.figure(figsize=(5,4))
im = plt.imshow(root.image) # later use a.set_data(new_data)
ax = plt.gca()
ax.set_xticklabels([]) 
ax.set_yticklabels([])

# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def rotate(*args):
    print 'rotate button press...'
    root.image = ndimage.rotate(root.image, 90)
    im.set_data(root.image)
    canvas.draw()

那似乎可以工作,但只能一次。如果我再次按旋转按钮,它似乎不起作用。(我需要以某种方式保存图像的新状态吗?)另外,可能与此无关,它似乎是镜像图像,而不是所需的旋转90度。 - not link
是的,这是因为您总是将原始“image”旋转90度。我会更新另一个修复程序,但最好重新设计Tkinter.Frame的子类,以便保存应用程序的属性......但那是另一个问题。 - Fiver
在嵌入时不应导入 pyplot - tacaswell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接