修复包含可滚动图形 Canvas 的 Canvas 的大小 CanvasTkAgg
Fix size of the Canvas who contains a Scrollable FigureCanvasTkAgg
我想问你有没有人可以修复ScrollableTkAggX
,
问题是网格位置的tk.Canvas()
或tk.Tk()
总是需要设置gridrowconfigure
和columnconfigure
, 要使小部件展开和调整大小,在正常情况下我们可以为小部件设置 width
和 height
以获得预定义的 window ,但在这种情况下,我不能这样做是因为 ScrollableTkAggX(tk.Canvas)
它会自动调整大小。
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.colors import to_hex
class ScrollableTkAggX(tk.Canvas):
def __init__(self, figure, master, **kw):
# --- create canvas with scrollbar ---
facecolor = str(to_hex(figure.get_facecolor()))
super(ScrollableTkAggX, self).__init__(master, **kw) # , background=facecolor
self.grid(row=0, column=0, sticky=tk.NSEW)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self) # , background=facecolor
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
self.TkAgg = FigureCanvasTkAgg(figure, master=self.fig_wrapper)
self.TkAggWidget = self.TkAgg.get_tk_widget()
self.TkAggWidget.configure(background=facecolor)
self.TkAggWidget.grid(row=0, column=0, sticky=tk.NSEW)
self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.xview)
self.hbar.grid(row=1, column=0, sticky=tk.EW)
self.configure(xscrollcommand=self.hbar.set, scrollregion=self.bbox(tk.ALL))
# when all widgets are in canvas
self.bind('<Configure>', self.on_configure_y)
# --- put frame in canvas ---
self.canvas_frame = self.create_window((0, 0), window=self.fig_wrapper, anchor=tk.NW)
# expand canvas_frame when canvas changes its size
def on_configure_y(self, event):
# when all widgets are in canvas
canvas_height = event.height
self.itemconfigure(self.canvas_frame, height=canvas_height)
# update scrollregion after starting 'mainloop' - 20
self.configure(scrollregion=self.bbox(tk.ALL))
def on_configure_x(self, width):
# when all widgets are in canvas
self.itemconfigure(self.canvas_frame, width=width)
# update scrollregion after starting 'mainloop'
self.configure(scrollregion=self.bbox(tk.ALL))
def Draw(self, width):
self.on_configure_x(width)
self.TkAgg.draw()
self.xview_moveto(0)
if __name__ == '__main__':
win = tk.Tk()
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(fig, win)
# try like that and disable them to understand what the problem
win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)
# like that
# win.rowconfigure(0, weight=1)
# win.columnconfigure(0, weight=1)
win.mainloop()
或与其他 tk.Canvas()
if __name__ == '__main__':
win = tk.Tk()
cnv = tk.Canvas(win, width=200, height=200)
cnv.grid(row=0, column=0, sticky=tk.NSEW)
# try like that and disable them to understand what the problem
cnv.rowconfigure(0, weight=1)
cnv.columnconfigure(0, weight=1)
# like that
# cnv.rowconfigure(0, weight=1)
# cnv.columnconfigure(0, weight=1)
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(fig, cnv)
# try like that and disable them to understand what the problem
win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)
win.mainloop()
这是一个非常奇怪的解决方案
步骤:
delete self.on_configure_y
add height
in call class and set it initial in self.create_window
finaly call and set first tk.Canvas(win)
, call and set second ScrollableTkAggX(win)
in same position grid
one under other.
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.colors import to_hex
class ScrollableTkAggX(tk.Canvas):
def __init__(self, figure, height, master, **kw):
self.height = height
facecolor = str(to_hex(figure.get_facecolor()))
# --- create canvas with scrollbar ---
super(ScrollableTkAggX, self).__init__(master, height=self.height, background=facecolor, **kw)
self.grid(row=0, column=0, sticky=tk.NSEW)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self, background=facecolor)
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
self.TkAgg = FigureCanvasTkAgg(figure, master=self.fig_wrapper)
self.TkAggWidget = self.TkAgg.get_tk_widget()
self.TkAggWidget.configure(background=facecolor)
self.TkAggWidget.grid(row=0, column=0, sticky=tk.NSEW)
self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.xview)
self.hbar.grid(row=1, column=0, sticky=tk.EW)
# --- put frame in canvas ---
self.canvas_frame = self.create_window((0, 0), window=self.fig_wrapper, height=self.height, anchor=tk.NW)
self.configure(xscrollcommand=self.hbar.set, scrollregion=self.bbox(tk.ALL))
# expand canvas_frame when canvas changes its size
def on_configure_x(self, width):
# when all widgets are in canvas
self.itemconfigure(self.canvas_frame, width=width)
# update scrollregion after starting 'mainloop'
self.configure(scrollregion=self.bbox(tk.ALL))
def Draw(self, width):
self.on_configure_x(width)
self.TkAgg.draw()
self.xview_moveto(0)
if __name__ == '__main__':
win = tk.Tk()
cnv = tk.Canvas(win, width=200, height=200)
cnv.grid(row=0, column=0, sticky=tk.NSEW)
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(figure=fig, master=win, height=200)
tkagg.grid(row=0, column=0, sticky=tk.NSEW)
win.mainloop()
我想问你有没有人可以修复ScrollableTkAggX
,
问题是网格位置的tk.Canvas()
或tk.Tk()
总是需要设置gridrowconfigure
和columnconfigure
, 要使小部件展开和调整大小,在正常情况下我们可以为小部件设置 width
和 height
以获得预定义的 window ,但在这种情况下,我不能这样做是因为 ScrollableTkAggX(tk.Canvas)
它会自动调整大小。
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.colors import to_hex
class ScrollableTkAggX(tk.Canvas):
def __init__(self, figure, master, **kw):
# --- create canvas with scrollbar ---
facecolor = str(to_hex(figure.get_facecolor()))
super(ScrollableTkAggX, self).__init__(master, **kw) # , background=facecolor
self.grid(row=0, column=0, sticky=tk.NSEW)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self) # , background=facecolor
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
self.TkAgg = FigureCanvasTkAgg(figure, master=self.fig_wrapper)
self.TkAggWidget = self.TkAgg.get_tk_widget()
self.TkAggWidget.configure(background=facecolor)
self.TkAggWidget.grid(row=0, column=0, sticky=tk.NSEW)
self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.xview)
self.hbar.grid(row=1, column=0, sticky=tk.EW)
self.configure(xscrollcommand=self.hbar.set, scrollregion=self.bbox(tk.ALL))
# when all widgets are in canvas
self.bind('<Configure>', self.on_configure_y)
# --- put frame in canvas ---
self.canvas_frame = self.create_window((0, 0), window=self.fig_wrapper, anchor=tk.NW)
# expand canvas_frame when canvas changes its size
def on_configure_y(self, event):
# when all widgets are in canvas
canvas_height = event.height
self.itemconfigure(self.canvas_frame, height=canvas_height)
# update scrollregion after starting 'mainloop' - 20
self.configure(scrollregion=self.bbox(tk.ALL))
def on_configure_x(self, width):
# when all widgets are in canvas
self.itemconfigure(self.canvas_frame, width=width)
# update scrollregion after starting 'mainloop'
self.configure(scrollregion=self.bbox(tk.ALL))
def Draw(self, width):
self.on_configure_x(width)
self.TkAgg.draw()
self.xview_moveto(0)
if __name__ == '__main__':
win = tk.Tk()
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(fig, win)
# try like that and disable them to understand what the problem
win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)
# like that
# win.rowconfigure(0, weight=1)
# win.columnconfigure(0, weight=1)
win.mainloop()
或与其他 tk.Canvas()
if __name__ == '__main__':
win = tk.Tk()
cnv = tk.Canvas(win, width=200, height=200)
cnv.grid(row=0, column=0, sticky=tk.NSEW)
# try like that and disable them to understand what the problem
cnv.rowconfigure(0, weight=1)
cnv.columnconfigure(0, weight=1)
# like that
# cnv.rowconfigure(0, weight=1)
# cnv.columnconfigure(0, weight=1)
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(fig, cnv)
# try like that and disable them to understand what the problem
win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)
win.mainloop()
这是一个非常奇怪的解决方案
步骤:
delete
self.on_configure_y
add
height
in call class and set it initial inself.create_window
finaly call and set first
tk.Canvas(win)
, call and set secondScrollableTkAggX(win)
in same positiongrid
one under other.
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.colors import to_hex
class ScrollableTkAggX(tk.Canvas):
def __init__(self, figure, height, master, **kw):
self.height = height
facecolor = str(to_hex(figure.get_facecolor()))
# --- create canvas with scrollbar ---
super(ScrollableTkAggX, self).__init__(master, height=self.height, background=facecolor, **kw)
self.grid(row=0, column=0, sticky=tk.NSEW)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self, background=facecolor)
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
self.TkAgg = FigureCanvasTkAgg(figure, master=self.fig_wrapper)
self.TkAggWidget = self.TkAgg.get_tk_widget()
self.TkAggWidget.configure(background=facecolor)
self.TkAggWidget.grid(row=0, column=0, sticky=tk.NSEW)
self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.xview)
self.hbar.grid(row=1, column=0, sticky=tk.EW)
# --- put frame in canvas ---
self.canvas_frame = self.create_window((0, 0), window=self.fig_wrapper, height=self.height, anchor=tk.NW)
self.configure(xscrollcommand=self.hbar.set, scrollregion=self.bbox(tk.ALL))
# expand canvas_frame when canvas changes its size
def on_configure_x(self, width):
# when all widgets are in canvas
self.itemconfigure(self.canvas_frame, width=width)
# update scrollregion after starting 'mainloop'
self.configure(scrollregion=self.bbox(tk.ALL))
def Draw(self, width):
self.on_configure_x(width)
self.TkAgg.draw()
self.xview_moveto(0)
if __name__ == '__main__':
win = tk.Tk()
cnv = tk.Canvas(win, width=200, height=200)
cnv.grid(row=0, column=0, sticky=tk.NSEW)
fig = Figure(figsize=(2, 2), dpi=120, facecolor='#212121')
mpl_white_rgb = ((255. / 255.), (255. / 255.), (255. / 255.))
fig.text(0, 0.5, 'test', fontsize=72, color=mpl_white_rgb)
tkagg = ScrollableTkAggX(figure=fig, master=win, height=200)
tkagg.grid(row=0, column=0, sticky=tk.NSEW)
win.mainloop()