在 tkinter Toplevel 中调整 matplotlib 图的大小
Resizing a matplotlib plot in a tkinter Toplevel
我有一些代码可以在 tkinter 顶层小部件中打开一个图。当我抓住顶层的一角来调整它的大小时,我希望绘图与 window.
一起调整大小
import Tkinter
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
from matplotlib.figure import Figure
class grapher_gui(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.graph()
def graph(self):
x_vals = [0,3,10,15]
y_vals = [232,120,45,23]
toplevel = Tkinter.Toplevel(width=2000)
figure = Figure(figsize=(10,5))
ax = figure.add_subplot(111)
plot = ax.plot(x_vals, y_vals, 'k-')
ax.set_xlabel('Time')
ax.set_ylabel('Numbers')
ax.set_title('Title')
canvas = FigureCanvasTkAgg(figure, master=toplevel)
canvas.show()
canvas.get_tk_widget().grid(row=0)
toolbar = NavigationToolbar2TkAgg(canvas, toplevel)
toolbar.grid(row=1, sticky=Tkinter.W)
toolbar.update()
toplevel.mainloop()
if __name__ == "__main__":
app = grapher_gui(None)
app.title('Grapher')
app.mainloop()
我唯一能想到的尝试是将 sticky='NSEW'
添加到 canvas.get_tk_widget().grid(row=0)
,但这不起作用。
你必须 bind an event to the window resize - 换句话说,不是让程序监视鼠标点击之类的事情并在它发生时做一些事情,而是让程序监视 window 被调整大小并在发生这种情况时采取行动。
在graph()
中添加:
self.toplevel.bind("<Configure>", resize)
然后将变量设为实例变量(例如 self.toplevel
而不是 toplevel
)以便您可以从其他方法中引用它们。
然后添加一个实例方法 def resize(event):
,它可以执行您需要执行的所有操作,以重新绘制具有新尺寸的绘图。您可以通过访问 toplevel.winfo_height()
和 toplevel.winfo_width()
来根据 Toplevel
window 的尺寸确定大小(添加 self
如果您已将其设为实例变量).
当 Toplevel
window 调整大小时,该事件将 "seen" 并路由到给定的回调(绑定到该事件的方法)。
这里有一个小例子,当你调整 root
window 的大小时打印它的大小:
>>> import tkinter as tk
>>> root = tk.Tk()
>>> def onsize(event):
... print(root.winfo_width(), root.winfo_height())
...
>>> root.bind("<Configure>", onsize)
对了,you only need to call mainloop()
once,在main
区。不要为每个 Toplevel
window.
调用它
尝试使用 pack
和 expand=True
而不是 grid
和 sticky
。这个简化的示例对我有用,并且图表会使用 window:
调整大小
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import Tkinter as tk
import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("Dashboard")
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
a.scatter([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
canvas1=FigureCanvasTkAgg(f,master)
canvas1.show()
canvas1.get_tk_widget().pack(side="top",fill='both',expand=True)
canvas1.pack(side="top",fill='both',expand=True)
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
我知道这可能很困难,具体取决于您的 gui 使用 pack 进行重新设计的程度...但可能值得而不是制作自定义调整大小事件处理程序。不过,我确实很同情,如果网格和粘性适用于图表,那就太好了:/
我有一些代码可以在 tkinter 顶层小部件中打开一个图。当我抓住顶层的一角来调整它的大小时,我希望绘图与 window.
一起调整大小import Tkinter
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
from matplotlib.figure import Figure
class grapher_gui(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.graph()
def graph(self):
x_vals = [0,3,10,15]
y_vals = [232,120,45,23]
toplevel = Tkinter.Toplevel(width=2000)
figure = Figure(figsize=(10,5))
ax = figure.add_subplot(111)
plot = ax.plot(x_vals, y_vals, 'k-')
ax.set_xlabel('Time')
ax.set_ylabel('Numbers')
ax.set_title('Title')
canvas = FigureCanvasTkAgg(figure, master=toplevel)
canvas.show()
canvas.get_tk_widget().grid(row=0)
toolbar = NavigationToolbar2TkAgg(canvas, toplevel)
toolbar.grid(row=1, sticky=Tkinter.W)
toolbar.update()
toplevel.mainloop()
if __name__ == "__main__":
app = grapher_gui(None)
app.title('Grapher')
app.mainloop()
我唯一能想到的尝试是将 sticky='NSEW'
添加到 canvas.get_tk_widget().grid(row=0)
,但这不起作用。
你必须 bind an event to the window resize - 换句话说,不是让程序监视鼠标点击之类的事情并在它发生时做一些事情,而是让程序监视 window 被调整大小并在发生这种情况时采取行动。
在graph()
中添加:
self.toplevel.bind("<Configure>", resize)
然后将变量设为实例变量(例如 self.toplevel
而不是 toplevel
)以便您可以从其他方法中引用它们。
然后添加一个实例方法 def resize(event):
,它可以执行您需要执行的所有操作,以重新绘制具有新尺寸的绘图。您可以通过访问 toplevel.winfo_height()
和 toplevel.winfo_width()
来根据 Toplevel
window 的尺寸确定大小(添加 self
如果您已将其设为实例变量).
当 Toplevel
window 调整大小时,该事件将 "seen" 并路由到给定的回调(绑定到该事件的方法)。
这里有一个小例子,当你调整 root
window 的大小时打印它的大小:
>>> import tkinter as tk
>>> root = tk.Tk()
>>> def onsize(event):
... print(root.winfo_width(), root.winfo_height())
...
>>> root.bind("<Configure>", onsize)
对了,you only need to call mainloop()
once,在main
区。不要为每个 Toplevel
window.
尝试使用 pack
和 expand=True
而不是 grid
和 sticky
。这个简化的示例对我有用,并且图表会使用 window:
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import Tkinter as tk
import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("Dashboard")
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
a.scatter([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
canvas1=FigureCanvasTkAgg(f,master)
canvas1.show()
canvas1.get_tk_widget().pack(side="top",fill='both',expand=True)
canvas1.pack(side="top",fill='both',expand=True)
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
我知道这可能很困难,具体取决于您的 gui 使用 pack 进行重新设计的程度...但可能值得而不是制作自定义调整大小事件处理程序。不过,我确实很同情,如果网格和粘性适用于图表,那就太好了:/