2013-10-26 3 views
3

Я пытаюсь обновить данные в окне Matplotlib imshow в Tkinter GUI, пример моего кода выглядит следующим образом:обновление Matplotlib imshow изнутри графического интерфейса Tkinter

#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(), а затем хотите обновить корневое окно gui с помощью root.update(). При выполнении выполняется печать строки «Повернуть кнопку нажмите ...», но, похоже, нет. Нужно ли мне передать дескриптор изображения функции вращения каким-либо образом или вернуть повернутое изображение?

+1

не импортируйте 'pyplot', если вы встраиваете. Вы в конечном итоге с дуэли gui основные петли. – tacaswell

+0

@tcaswell Это имеет смысл, но если я не использую 'pylot', как я могу получить доступ к' imshow() '? –

+0

См. Http://stackoverflow.com/questions/14254379/how-can-i-attach-a-pyplot-function-to-a-figure-instance/14261698#14261698 – tacaswell

ответ

2

Полотно должно быть перерисованы, попробуйте следующее:

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

Update, чтобы сохранить вращающаяся

Примечание это экономия 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() 
+0

Это похоже на работу, но только один раз. Если я снова нажму кнопку поворота, он, похоже, ничего не сделает. (Нужно ли каким-то образом сохранить новое состояние изображения?) И на потенциально несвязанной ноте кажется, что это зеркало изображения, а не поворот 90 по желанию. –

+0

Да, это потому, что вы всегда вращаете оригинал 'image' на 90 градусов. Я обновлю еще одно исправление, но вам лучше отказаться от рефакторинга, чтобы создать свой собственный подкласс Tkinter.Frame, чтобы вы могли сохранять атрибуты вашего приложения ... но это еще один вопрос. – Fiver

+0

Вы не должны импортировать 'pyplot' при встраивании. – tacaswell

Смежные вопросы