You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib工具栏在PySimpleGUI或Tkinter中不显示图标,仅显示重叠文字按钮

Matplotlib工具栏在PySimpleGUI或Tkinter中不显示图标,仅显示重叠文字按钮

看起来你在Mac环境下遇到了Matplotlib工具栏嵌入PySimpleGUI后,图标不显示、按钮文字重叠的问题,我之前在Mac上开发时也碰到过类似情况,结合你的版本信息(Python3.9.12、Matplotlib3.7.1、PySimpleGUI4.60.4),给你几个针对性的解决方案:

问题根源分析

Mac系统下的Tkinter对Matplotlib的图标渲染有特殊兼容情况,再加上你布局里的控制栏Canvas没有设置足够尺寸,导致按钮挤在一起文字重叠;另外你自定义的Toolbar类没有额外功能,反而可能干扰了原生工具栏的图标加载逻辑。

具体解决方案

1. 显式指定Matplotlib后端

在导入Matplotlib相关模块后,强制指定使用TkAgg后端,避免Mac默认后端导致图标加载失败:

import matplotlib.pyplot as plt
plt.switch_backend('TkAgg')  # 新增这一行
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

2. 移除自定义Toolbar类,使用原生组件

你自定义的Toolbar类没有添加任何额外功能,反而可能破坏了原生工具栏的图标加载流程。直接删掉这个类,在draw_figure_w_toolbar函数中使用原生的NavigationToolbar2Tk:

def draw_figure_w_toolbar(canvas, fig, canvas_toolbar):
    if canvas.children:
        for child in canvas.winfo_children():
            child.destroy()
    if canvas_toolbar.children:
        for child in canvas_toolbar.winfo_children():
            child.destroy()

    figure_canvas_agg = FigureCanvasTkAgg(fig, master=canvas)
    figure_canvas_agg.draw()
    # 使用原生工具栏,替换自定义的Toolbar类
    toolbar = NavigationToolbar2Tk(figure_canvas_agg, canvas_toolbar)
    toolbar.update()

    figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)

3. 调整控制栏Canvas的尺寸

你的布局中controls_cv这个Canvas没有设置尺寸,导致工具栏按钮挤在一起重叠。修改布局里的Canvas定义,给它一个合适的宽度和高度:

[sg.T('Controls:')],
[sg.Canvas(key='controls_cv', size=(800, 40))],  # 新增size参数

4. 升级PySimpleGUI到最新版本

你使用的4.60.4版本相对较旧,新版本修复了很多Mac平台的兼容问题。执行以下命令升级:

pip install --upgrade PySimpleGUI

修改后的完整代码示例

import PySimpleGUI as sg
import numpy as np

"""
Embedding the Matplotlib toolbar into your application
"""

# ------------------------------- This is to include a matplotlib figure in a Tkinter canvas
import matplotlib.pyplot as plt
plt.switch_backend('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

def draw_figure_w_toolbar(canvas, fig, canvas_toolbar):
    if canvas.children:
        for child in canvas.winfo_children():
            child.destroy()
    if canvas_toolbar.children:
        for child in canvas_toolbar.winfo_children():
            child.destroy()

    figure_canvas_agg = FigureCanvasTkAgg(fig, master=canvas)
    figure_canvas_agg.draw()
    toolbar = NavigationToolbar2Tk(figure_canvas_agg, canvas_toolbar)
    toolbar.update()

    figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)

# ------------------------------- PySimpleGUI CODE
layout = [
    [sg.T('Graph: y=sin(x)')],
    [sg.B('Plot'), sg.B('Exit')],
    [sg.T('Controls:')],
    [sg.Canvas(key='controls_cv', size=(800, 40))],
    [sg.T('Figure:')],
    [sg.Column(
        layout=[
            [sg.Canvas(key='fig_cv',
                       # it's important that you set this size
                       size=(400 * 2, 400)
                       )]
        ],
        background_color='#DAE0E6',
        pad=(0, 0)
    )],
    [sg.B('Alive?')]
]

window = sg.Window('Graph with controls', layout)

if __name__ == "__main__":
    while True:
        event, values = window.read()
        print(event, values)
        if event in (sg.WIN_CLOSED, 'Exit'):  # always,  always give a way out!
            break
        elif event == 'Plot':
            # ------------------------------- PASTE YOUR MATPLOTLIB CODE HERE
            plt.figure(1)
            fig = plt.gcf()
            DPI = fig.get_dpi()
            # ------------------------------- you have to play with this size to reduce the movement error when the mouse hovers over the figure, it's close to canvas size
            fig.set_size_inches(404 * 2 / float(DPI), 404 / float(DPI))
            # -------------------------------
            x = np.linspace(0, 2 * np.pi)
            y = np.sin(x)
            plt.plot(x, y)
            plt.title('y=sin(x)')
            plt.xlabel('X')
            plt.ylabel('Y')
            plt.grid()
            # ------------------------------- Instead of plt.show()
            draw_figure_w_toolbar(window['fig_cv'].TKCanvas, fig, window['controls_cv'].TKCanvas)
    window.close()

如果以上方案还是无法解决问题,可以尝试重置Matplotlib的配置文件(删除~/.matplotlib目录下的缓存文件),或者检查Mac上的Tkinter是否为完整版本(Python3.9自带的Tkinter一般没问题,若缺失可以通过Homebrew安装tcl-tk)。

备注:内容来源于stack exchange,提问作者WBT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 10:47:46