这是我的第一个tkInter应用程序。我想在tkinter画布上画一个matplotlib图。我阅读了以下链接来构建它:
但结果并不令人满意:在回调方法中没有刷新数字,但只有在我运行应用程序的“重置”按钮时才会刷新。有人能告诉我如何在“PlotCallback”中刷新数字/画布吗?
提前致谢!
#!/usr/bin/env python
# -*- coding: utf8 -*-
import os
import numpy as np
import Tkinter
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkFileDialog
import tkMessageBox
#=========================
# App Class
#=========================
class Visu(Tkinter.Frame):
"""Main Frame for data visualization
"""
#------------------------------------
def __init__(self, parent, **kwargs):
"""Initialisation des widgets
"""
### USED VARIABLES (for file and data processing)
self.dataToPlot = []
self.itmsToPlot = []
self.presentsItems = []
self.chBtnVarLst = [] # list of "CheckButton" states for items selection
self.chBtnLst = [] # list of "CheckButton" labels
self.fic = ""
self.parent = parent
### IHM ###
Tkinter.Frame.__init__( self, parent, **kwargs )
self.pack(fill=Tkinter.BOTH)
# Create Menu Bar
menuBar = Tkinter.Menu( self )
menuFic = Tkinter.Menu( menuBar )
menuFic.add_command(label="Open", command = self.OpenCallback)
menuFic.add_separator()
menuFic.add_command(label="Quit", command = self.quit)
menuHlp = Tkinter.Menu( menuBar )
menuHlp.add_command(label="Help", command = self.HelpCallback)
menuBar.add_cascade(label = "File", menu = menuFic)
menuBar.add_cascade(label = "Help", menu = menuHlp)
parent.config(menu = menuBar)
# Create the Canvas for the plot figure
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2*np.pi*t)
self.ax.plot(t,s)
self.canvas = FigureCanvasTkAgg(self.fig, master = self)
self.canvas.show()
self.canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2TkAgg(self.canvas, self)
toolbar.update()
self.canvas._tkcanvas.pack(side=Tkinter.TOP, expand=1)
# Create controls
self.dataFrame = Tkinter.LabelFrame( self, text = "Available data" )
self.defButton = Tkinter.Checkbutton( self.dataFrame,
text = "Empty",
justify = Tkinter.LEFT,
state = Tkinter.DISABLED).pack()
self.dataFrame.pack()
# Create Buttons
self.BtnPlot = Tkinter.Button(self, text = "Plot", command = self.PlotCallback, state = Tkinter.DISABLED)
self.BtnPlot.pack(fill = Tkinter.BOTH, expand=1)
self.BtnRaZ = Tkinter.Button(self, text = "Reset", command = self.ResetCallback, state = Tkinter.DISABLED)
self.BtnRaZ.pack(fill = Tkinter.BOTH, expand=1)
#----------------------
def OpenCallback(self):
"""Open data file and add selection check buttons
"""
# Open file
options = {}
options['defaultextension'] = '.txt'
options['initialdir'] = '..'
options['title'] = 'Choix du fichier'
options['filetypes'] = [('text files', '.txt'),('all files', '.*')]
filename = tkFileDialog.askopenfilename(**options)
self.fic = os.path.basename( filename )
# Reader file header
f = open(filename)
self.presentsItems = f.readline().split()
f.close()
# Read data
self.dataToPlot = np.loadtxt(filename, skiprows=1)
#--- Frame to select items to be drawn ---
cnt = 0
for c in self.presentsItems:
cbVar = Tkinter.StringVar()
w = Tkinter.Checkbutton(self.dataFrame,
text = c,
variable = cbVar,
justify = Tkinter.LEFT,
onvalue = c)
w.deselect()
self.chBtnVarLst.append(cbVar)
self.chBtnLst.append(w)
w.grid(row = cnt % 10, column = cnt / 10)
cnt += 1
# Buttons activation
self.BtnPlot['state'] = Tkinter.NORMAL
self.BtnRaZ['state'] = Tkinter.NORMAL
#----------------------
def HelpCallback(self):
"""Instructions on how to use the program
"""
tkMessageBox.showinfo("Usage", "Work in progress...")
#----------------------
def PlotCallback(self):
# Read chosen items
for cbVar in self.chBtnVarLst:
if cbVar.get() != "0":
self.itmsToPlot.append( cbVar.get() )
# Plot those items
self.ax.cla()
self.fig.suptitle( self.fic )
for itm in self.itmsToPlot:
k = self.presentsItems.index(itm)
self.ax.plot(self.dataToPlot[:,k],label=itm)
self.ax.set_xlabel("Frame number")
self.ax.legend()
self.canvas.get_tk_widget().update()
self.update()
self.fig.canvas.draw()
#-----------------------
def ResetCallback(self):
"""Forgets the items and data, destroy associated buttons
"""
for cb in self.chBtnLst:
cb.destroy()
self.dataToPlot = []
self.itmsToPlot = []
self.presentsItems = []
self.chBtnLst = []
self.chBtnVarLst = []
self.fic = ""
#========
# Main
#========
if __name__=='__main__':
root = Tkinter.Tk()
root.wm_title("Visu XDE")
maVisu = Visu( root )
maVisu.mainloop()
使用Python 2.7.3,matplotlib 1.1.1rc,Tkinter修订版:81008在Ubuntu 12.04上测试(不幸的是我需要一个仅在12.04中存在的特殊模拟框架)。
答案 0 :(得分:0)
实际上,问题不在于matplotlib,而是没有正确处理的检查按钮,这不会引发异常或错误,但不要让GUI刷新。创建最小,完整和可验证的例子揭示了它......感谢Sun Bear和Goyo的宝贵帮助。