如何让ImageCanvasTkAgg与Scrollbar一起使用

时间:2015-09-14 18:55:05

标签: python matplotlib tkinter

我想在tkinter应用程序中绘图。在最终的节目中,将有许多垂直排列的子图,而不是适合屏幕。所以我希望有一个合理大小的窗口,滚动条向下滚动。

从这里找到的Canvas示例开始Tkinter Scrollbar Patterns我创建了这个我努力的最小例子:

#!/usr/bin/python

from Tkinter import Tk, Frame, Canvas, Scrollbar, HORIZONTAL, VERTICAL, BOTH, X, Y, BOTTOM, RIGHT, LEFT, S, N, W, E
from numpy import arange, sin
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class Test(Tk):
    def __init__(self):
        Tk.__init__(self, None)
        self.frame=Frame(None)
        self.frame.columnconfigure(0,weight=1)
        self.frame.rowconfigure(0,weight=1)

        self.frame.grid(row=0,column=0, sticky=W+E+N+S)

        fig = Figure()

        xval = arange(200)/10.
        yval = sin(xval)

        ax1 = fig.add_subplot(111)
        ax1.plot(xval, yval)

        self.hbar=Scrollbar(self.frame,orient=HORIZONTAL)
        self.vbar=Scrollbar(self.frame,orient=VERTICAL)

        self.canvas=FigureCanvasTkAgg(fig, master=self.frame)
        self.canvas.get_tk_widget().config(bg='#FFFFFF',scrollregion=(0,0,500,500))
        self.canvas.get_tk_widget().config(width=300,height=300)
        self.canvas.get_tk_widget().config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)
        self.canvas.get_tk_widget().grid(row=0, column=0, sticky=W+E+N+S)

        self.hbar.grid(row=1, column=0, sticky=W+E)
        self.hbar.config(command=self.canvas.get_tk_widget().xview)
        self.vbar.grid(row=0, column=1, sticky=N+S)
        self.vbar.config(command=self.canvas.get_tk_widget().yview)

        self.frame.config(width=100, height=100) # this has no effect

if __name__ == '__main__':

    app = Test()
    app.mainloop()

以下是我的两个主要问题:

  1. 当我调整窗口大小时,滚动条是静态的,即如果我用鼠标拖动减小窗口大小,它会与其余的图形一起消失
  2. 更重要的是:如果我在代码中增加画布大小,窗口大小也会增加。我尝试添加self.canvas.get_tk_widget().grid_propagate(0)但没有成功......
  3. 我需要窗口大小小于开头的绘图大小。

1 个答案:

答案 0 :(得分:1)

解决方案:

if __name__ == '__main__':

    app = Test()
    app.rowconfigure( 0, weight=1 )     # You need to add this. 
    app.columnconfigure( 0, weight=1 )  # You need to add this.

    app.mainloop()

您的Tk窗口中有一个子tk.Frame小部件,即Tk.frame,位于Tk窗口的(0,0)网格位置。默认情况下,Tk.frame的大小将是其子窗口小部件的大小,当前是具有FigureCanvasTkAgg小部件的matplotlib后端tk.Canvas对象,即Tk.frame.canvas.get_tk_widget() ,您已将其设置为300x300像素宽和高。

您需要这两行内容来指示Tk窗口的网格单元(0,0)是可拉伸的。也就是说,单元格(0,0)的边框应拉伸为“始终触摸Tk窗口的边框”。此操作可确保Tk.frame的大小始终是Tk窗口的大小。

当前,当您调整Tk窗口的大小而没有添加任何行时,您会看到Tk窗口的大小进行了调整,而Tk.frame的大小保持不变,且宽度为300x300像素。 / p>