在Tkinter窗口嵌入2x2绘图时出现重复弹窗问题求助
解决CTkFrame中Matplotlib绘图重复弹窗的问题
问题根源是你在初始化方法中调用了plt.show(),这会强制创建一个独立的Matplotlib原生窗口;同时plt.figure()默认会绑定到这个全局窗口,再加上你用FigureCanvasTkAgg把同一个figure嵌入到CTkFrame里,就导致了重复显示。
解决步骤:
- 移除
plt.show()调用:在Tkinter/CTk环境下嵌入Matplotlib绘图,不需要这个方法——它是用来显示Matplotlib独立窗口的。 - 避免依赖pyplot全局状态:直接使用
matplotlib.figure.Figure创建绘图对象,而非plt.figure(),彻底和pyplot的全局窗口解绑。 - 绑定画布引用用于更新:保存
FigureCanvasTkAgg的引用,实时更新时只刷新Tkinter画布,不触发pyplot的全局窗口操作。
修改后的核心代码:
from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import customtkinter as ctk class Testing(ctk.CTkFrame): def __init__(self, parent, controller): """Initialise the testing window""" ctk.CTkFrame.__init__(self, parent) plt.ion() # 保留交互模式用于实时更新 # 移除plt.show() def run(self): # 直接创建Figure对象,脱离pyplot全局状态 self.fig = Figure(figsize=(8,8)) self.ax1 = self.fig.add_subplot(221) self.ax2 = self.fig.add_subplot(222) self.ax3 = self.fig.add_subplot(223) self.ax4 = self.fig.add_subplot(224) canvas = FigureCanvasTkAgg(self.fig, self) canvas._tkcanvas.grid(row=1, rowspan=3, columnspan=3, column=5) self.canvas = canvas # 保存画布引用,方便后续更新 self.live_plot() def live_plot(self): # 示例:更新子图数据 self.ax1.clear() self.ax1.plot([1,2,3], [4,5,6]) # ... 其他子图更新逻辑 # 仅刷新CTkFrame内的画布 self.canvas.draw() # 定时重复调用实现实时更新 self.after(100, self.live_plot)
关键说明:
- 用
Figure类替代plt.figure(),完全脱离pyplot的全局窗口管理,从根源避免额外弹窗。 - 移除
plt.show()后,绘图的显示完全由Tkinter窗口接管,不会触发Matplotlib原生窗口。 - 实时更新时调用
self.canvas.draw(),仅刷新CTkFrame中的绘图区域,确保显示唯一。
内容的提问来源于stack exchange,提问作者Governor
相关产品推荐
相关产品推荐

