我正在创建一个GUI,它应该在主窗口左侧显示一些小部件(例如按钮和比例尺)(或由'root=tk.Tk()
'创建的'root'和右侧的图表。该图将使用matplotlib和FigureCanvasTkAgg()
后端创建(类似于发现的here)。以下是我迄今为止编写的代码。Tkinter和Matplotlib:创建的画布的相对位置FigureCanvasTkAgg
import tkMessageBox, tkFileDialog
import sys
# Tkinter is for python 2; tkinter is for python 3
if sys.version_info[0] < 3:
import Tkinter as tk
else:
import tkinter as tk
class MainApp(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.parent.title('App')
# call the widgets
self.okButton()
self.quitButton()
self.readDataButton()
self.clearDataButton()
self.velScale()
self.canvas()
# print messages on the screen
def printMessage(self):
if (self.data):
print("Data is loaded and accessible from here (printMessage()).")
else:
print('No data loaded...')
### OK button
def okButton(self):
self.okButton = tk.Button(self, text='Test', command=self.printMessage)
self.okButton.grid()
### Quit button
def quitButton(self):
self.quitButton = tk.Button(self, text='Quit', command=self.confirmQuit)
self.quitButton.grid()
# confirm quitting
def confirmQuit(self):
answer = tkMessageBox.askyesno(title="App", message="Do you really want to quit?")
if (answer):
self.quit()
# Read data button
def readDataButton(self):
self.data = None
self.readDataButton = tk.Button(self, text='Import data', command=self.readData)
self.readDataButton.grid()
# reading data
def readData(self):
import os
fullPath = dataList = tkFileDialog.askopenfilename(initialdir='path/to/initialdir')
dataDir = os.path.split(fullPath)[0]+'/'
self.data = readData(fullPath)
# Clear data from current session
def clearDataButton(self):
self.clearData = tk.Button(self, text='Clear data', command=self.confirmClearData)
self.clearData.grid()
# confirm clearing data
def confirmClearData(self):
answer = tkMessageBox.askyesno(title="App", message="Are you sure you want to clear the loaded data?")
if (answer):
self.data = None
tkMessageBox.showwarning(title="App", message="Data has been deleted.")
# Velocity scale
def velScale(self):
self.velVar = tk.StringVar()
velLabel = tk.Label(self, text="Scale value:", textvariable=self.velVar)
velLabel.grid(row=4, column=0, columnspan=2, sticky=tk.W+tk.E)
velScale = tk.Scale(self, from_=-500, to=+500, orient=tk.HORIZONTAL, resolution=20,
sliderlength=20, showvalue=0,
length=200, width=20,
command=self.onVelScale)
velScale.grid(row=5, column=0)
# update velLabel
def onVelScale(self, val):
self.velVar.set("Scale value: {:+0.0f}".format(float(val)))
# Canvas
def canvas(self):
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
self.f = Figure(figsize=(4,2))
self.a = self.f.add_subplot(111)
self.a.plot([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
self.canvas = FigureCanvasTkAgg(self.f, master=self.parent)
self.canvas.show()
self.canvas.get_tk_widget().pack()
self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.parent)
self.toolbar.update()
self.canvas._tkcanvas.pack()
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x600+10+10")
root.resizable(0, 0)
MainApp(root).pack(side=tk.TOP)
root.mainloop()
结果是这样的:Screenshot of the App's main window。使用.grid()
作为按钮和比例小部件按预期工作(我可以通过指定row
和column
将它们放置在任何地方)。但是,我不能在画布部分具有相同的行为。似乎只有.pack()
将与画布一起工作(并且结果显示在上面的链接中)。
有没有人有关于如何解决这个问题的任何想法?或者我错过了什么?
谢谢你的任何建议。
首先,我不认为你需要调用'show'当你'网格'的数字,但其次你有一些代码可以在python 2或3中使用'tkinter',但你没有改变你为filedialogs或消息框输入,这些也在2和3之间变化。 –
嗨,@JamesKent!感谢您的意见。我已经改变了代码来相应地导入'tkMessageBox'和'tkFileDialog'到正在使用的Python版本。关于你对'.grid()'的评论,你能否详细说明一下? ;) – mairan