清除 Tkinter GUI 中每个选项卡的 canvas
Clearing the canvas for each tab in Tkinter GUI
我有一个复杂的图形用户界面,太长了post。我不明白如何从我的 Tkinter gui 中的图形中清除图形。我有一个选项卡式 gui,想在每个选项卡中绘制一个图形并清除每个选项卡中的图形。当我尝试这样做时,我遇到了与 canvas 有关的各种不同错误。我可以理解一个图形、一个轴、一个选项卡和一个框架,但是 canvas 似乎被称为图形的同义词,这看起来很奇怪(而且可能不正确)。
我看不出图和 canvas 之间有什么区别(有吗?),我在这里阅读的大多数文章和答案似乎都没有涵盖 canvas全部
Matplotlib 文档:
“数字
整个图。该图跟踪所有 child 轴、一些“特殊”艺术家(标题、图例等)和 canvas。 (不用太担心canvas,它很关键因为它是object绘图来获取您的情节,但作为用户,它 more-or-less 对您不可见)。一个图形可以有任意数量的轴,但要有用应该至少有一个。"
代码
import tkinter.filedialog
import os
import re
import tkinter as tk
from tkinter import ttk
import matplotlib
matplotlib.use("TkAgg") # this is the backend of matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import easygui
from matplotlib.legend_handler import HandlerLine2D
from scipy.stats import linregress
pd.set_option("display.max_rows", None, "display.max_columns", None)
#=====================================================================
# ROOT FIGURE FOR GUI
#=====================================================================
root = tk.Tk()
root.title("Tab Widget")
root.geometry("600x450")
tabControl = ttk.Notebook(root)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tabControl.add(tab1, text ='Circle cal drops')
tabControl.add(tab2, text ='OPW')
tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
tabControl.grid(column=0, row=0, sticky=tk.E+tk.W+tk.N+tk.S)
# TAB 1
# creating a frame (my_frame_1)
my_frame_1 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
fig = Figure(figsize=(4,4), dpi=100)
def clearPlot():
fig.clear()
canvas.draw_idle()
def plotData():
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [5, 6, 1, 3, 8], marker='.', c='r')
canvas = FigureCanvasTkAgg(fig, master = my_frame_1)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_2)
my_frame_2 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_2.pack(side=tk.RIGHT)
#---------------------------------------------------------------------
button1_cal = tk.Button(my_frame_2, text = "Clear Plot", command = clearPlot, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_2, text = "Plot \nData", command = plotData, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
# TAB 2
# creating a frame (my_frame_3)
my_frame_3 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_3.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
def clearPlotOpw():
pass
def plotDataOpw():
fig = Figure(figsize=(4,4), dpi=100)
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [8, 5, 1, 3, 11], marker='o', c='b')
canvas = FigureCanvasTkAgg(fig, master = my_frame_3)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_4)
my_frame_4 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_4.pack(side=tk.RIGHT)
button1_cal = tk.Button(my_frame_4, text = "Clear Plot", command = clearPlotOpw, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_4, text = "Plot \nData", command = plotDataOpw, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
root.mainloop()
print('\n'*4)
*** 期望的结果 ***
能够根据需要经常re-plot清除每个地块。
尝试使用清除绘图功能时的回溯
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/.../opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/.../Desktop/tk_gui_grid/basic_08.py", line 48, in clearPlot
canvas.draw_idle()
NameError: name 'canvas' is not defined
我知道 canvas 是未定义的,但是当我定义它时,情节根本没有被绘制。
这最终对我有用。
#MAKE A FIGURE OBJECT
my_figure4 = Figure(figsize = (4, 4), dpi = 100)
#MAKE A FRAME WIDGET
frame1 = tk.Frame(tab4, bd=2, relief=tk.GROOVE)
frame1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
frame2 = tk.Frame(tab4, bd=2, relief=tk.GROOVE)
frame2.pack(side=tk.RIGHT)
#MAKE A CANVAS OBJECT
my_canvas4 = FigureCanvasTkAgg(my_figure4, master = frame1) # creating the Tkinter canvas containing the Matplotlib figure
# TURN THE CANVAS OBJECT INTO A CANVAS WIDGET
my_canvas4.get_tk_widget().pack() # placing the canvas on the Tkinter window
my_canvas4.draw()
def plotData():
plot1 = my_figure4.add_subplot(111) # adding the subplot
x = [1,2,3,4,5]
y = [1, 2, 3, 4, 5]
plot1.plot(x, y, marker='o', c='y')
my_canvas4.draw()
def clearPlot():
my_figure4.clear()
my_canvas4.draw_idle()
我有一个复杂的图形用户界面,太长了post。我不明白如何从我的 Tkinter gui 中的图形中清除图形。我有一个选项卡式 gui,想在每个选项卡中绘制一个图形并清除每个选项卡中的图形。当我尝试这样做时,我遇到了与 canvas 有关的各种不同错误。我可以理解一个图形、一个轴、一个选项卡和一个框架,但是 canvas 似乎被称为图形的同义词,这看起来很奇怪(而且可能不正确)。
我看不出图和 canvas 之间有什么区别(有吗?),我在这里阅读的大多数文章和答案似乎都没有涵盖 canvas全部
Matplotlib 文档: “数字 整个图。该图跟踪所有 child 轴、一些“特殊”艺术家(标题、图例等)和 canvas。 (不用太担心canvas,它很关键因为它是object绘图来获取您的情节,但作为用户,它 more-or-less 对您不可见)。一个图形可以有任意数量的轴,但要有用应该至少有一个。"
代码
import tkinter.filedialog
import os
import re
import tkinter as tk
from tkinter import ttk
import matplotlib
matplotlib.use("TkAgg") # this is the backend of matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import easygui
from matplotlib.legend_handler import HandlerLine2D
from scipy.stats import linregress
pd.set_option("display.max_rows", None, "display.max_columns", None)
#=====================================================================
# ROOT FIGURE FOR GUI
#=====================================================================
root = tk.Tk()
root.title("Tab Widget")
root.geometry("600x450")
tabControl = ttk.Notebook(root)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tabControl.add(tab1, text ='Circle cal drops')
tabControl.add(tab2, text ='OPW')
tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
tabControl.grid(column=0, row=0, sticky=tk.E+tk.W+tk.N+tk.S)
# TAB 1
# creating a frame (my_frame_1)
my_frame_1 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
fig = Figure(figsize=(4,4), dpi=100)
def clearPlot():
fig.clear()
canvas.draw_idle()
def plotData():
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [5, 6, 1, 3, 8], marker='.', c='r')
canvas = FigureCanvasTkAgg(fig, master = my_frame_1)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_2)
my_frame_2 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_2.pack(side=tk.RIGHT)
#---------------------------------------------------------------------
button1_cal = tk.Button(my_frame_2, text = "Clear Plot", command = clearPlot, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_2, text = "Plot \nData", command = plotData, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
# TAB 2
# creating a frame (my_frame_3)
my_frame_3 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_3.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
def clearPlotOpw():
pass
def plotDataOpw():
fig = Figure(figsize=(4,4), dpi=100)
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [8, 5, 1, 3, 11], marker='o', c='b')
canvas = FigureCanvasTkAgg(fig, master = my_frame_3)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_4)
my_frame_4 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_4.pack(side=tk.RIGHT)
button1_cal = tk.Button(my_frame_4, text = "Clear Plot", command = clearPlotOpw, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_4, text = "Plot \nData", command = plotDataOpw, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
root.mainloop()
print('\n'*4)
*** 期望的结果 ***
能够根据需要经常re-plot清除每个地块。
尝试使用清除绘图功能时的回溯
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/.../opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/.../Desktop/tk_gui_grid/basic_08.py", line 48, in clearPlot
canvas.draw_idle()
NameError: name 'canvas' is not defined
我知道 canvas 是未定义的,但是当我定义它时,情节根本没有被绘制。
这最终对我有用。
#MAKE A FIGURE OBJECT
my_figure4 = Figure(figsize = (4, 4), dpi = 100)
#MAKE A FRAME WIDGET
frame1 = tk.Frame(tab4, bd=2, relief=tk.GROOVE)
frame1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
frame2 = tk.Frame(tab4, bd=2, relief=tk.GROOVE)
frame2.pack(side=tk.RIGHT)
#MAKE A CANVAS OBJECT
my_canvas4 = FigureCanvasTkAgg(my_figure4, master = frame1) # creating the Tkinter canvas containing the Matplotlib figure
# TURN THE CANVAS OBJECT INTO A CANVAS WIDGET
my_canvas4.get_tk_widget().pack() # placing the canvas on the Tkinter window
my_canvas4.draw()
def plotData():
plot1 = my_figure4.add_subplot(111) # adding the subplot
x = [1,2,3,4,5]
y = [1, 2, 3, 4, 5]
plot1.plot(x, y, marker='o', c='y')
my_canvas4.draw()
def clearPlot():
my_figure4.clear()
my_canvas4.draw_idle()