在 MatPlotLib 事件触发另一个 window 函数后,Return 到 PySimpleGUI 主 window 循环?

Return to PySimpleGUI main window loop after MatPlotLib event triggers another window function?

我有一个包含 Matplotlib 条形图的 PySimpleGUI window。我最近向它添加了一个事件,允许用户单击一个栏并访问基于栏标签的功能。这很好用……直到我在非 matplotlib 区域(例如我的 PSG 按钮)中单击一下。进行一些测试后,似乎只有当我调用新的、不同的 window 函数作为 on_click 事件函数 运行 的结果时,才会发生此问题。在我这里的示例中,如果我删除 another_window(),我不会遇到单击打印我的条形名称或点击 PSG 中的按钮的问题。问题是我需要触发其他 windows 并能够 return 到正常运行的主程序 window。我做错了什么?提前致谢!

import PySimpleGUI as sg
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib import pyplot as plt
from matplotlib.backend_bases import MouseButton


class Toolbar(NavigationToolbar2Tk):
    def __init__(self, *args, **kwargs):
        super(Toolbar, self).__init__(*args, **kwargs)

def on_click(event):
    ax = event.inaxes
    x = event.xdata
    lbls = ax.get_xticklabels()
    idx = int(x.round())
    lbl = lbls[idx]
    print('bar name is ', lbl.get_text())
    another_window()

def draw_figure(canvas, figure, canvas_toolbar, loc=(0, 0)): 
    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(figure, canvas)
    figure_canvas_agg.draw()
    toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
    toolbar.update()
    figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas_agg

def data():
    fig, ax = plt.subplots(figsize=(20,9), dpi=100)
    width = 0.95
    ax.tick_params(axis='x', labelrotation = 90, labelright=True)
    ax.set_ylabel('Stock Quantity')

    for x in range(5):
        bar_name = x
        bar_qty = x
        ax.bar(bar_name, bar_qty, width, color='red', label='Quantity')

    plt.subplots_adjust(top = 1, bottom = .15, right = 1, left = .03, hspace = 0, wspace = 0)
    plt.margins(0,0)
    plt.margins(x=0)
    return fig

def another_window():
    layout = [[sg.T('Hello')]]
    window = sg.Window(layout=layout, title='', size=(100,100))
    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED or event == 'Exit':
            window.Close()
            break

def main():

    team_buttons =  [[sg.T('Options', text_color='black',  font = 'Arial 18')],
            [sg.Button('Store Inventory', size = (17,1), font = 'Arial 14', k='-STORE BUTTON1-'), 
            sg.Button('Retrieve Inventory', size = (17,1), font = 'Arial 14', k='-RETRIEVE BUTTON1-'), 
            sg.Button('Exit', button_color = '#36454f', size = (17,1), font = 'Arial 14', k='-EXIT BUTTON1-')]]

    layoutMain = [[sg.Canvas(key=('-controls_cv-'))],
            [sg.Column(team_buttons, visible=True),],
            [sg.Canvas(size=(1920, 800), pad=((0,0),(0,0)), key='-CANVAS-', expand_x = True, expand_y = False, border_width = 50)]]

    windowMain = sg.Window('E-Stock', layoutMain, no_titlebar=False, size=(1920,1080), finalize=True, resizable=True)
    windowMain.maximize()

    fig = data()

    fig_photo = draw_figure(windowMain['-CANVAS-'].TKCanvas, fig, windowMain['-controls_cv-'].TKCanvas)
    cid = fig.canvas.mpl_connect('button_press_event', on_click)

    while True:
        event, values = windowMain.read()

        if event == '-STORE BUTTON1-':
            print('store part')

        if event == '-RETRIEVE BUTTON1-':
            print('retrieve part')

        if event == sg.WIN_CLOSED or event == 'Exit' or event == '-EXIT BUTTON1-':
            windowMain.Close()
            break

main()

不确定 fig.canvas.mpl_connect 有什么问题。 我的建议不是在事件处理程序中创建一个新的 window,而是为新的 window.

生成一个事件到 main_window
def on_click(event, win):
    ax = event.inaxes
    x = event.xdata
    lbls = ax.get_xticklabels()
    idx = int(x.round())
    lbl = lbls[idx]
    print('bar name is ', lbl.get_text())
    win.write_event_value('Another', None)
    cid = fig.canvas.mpl_connect('button_press_event', lambda event, win=windowMain:on_click(event, win))

    while True:
        event, values = windowMain.read()

        if event == '-STORE BUTTON1-':
            print('store part')

        if event == '-RETRIEVE BUTTON1-':
            print('retrieve part')

        if event == sg.WIN_CLOSED or event == 'Exit' or event == '-EXIT BUTTON1-':
            windowMain.Close()
            break

        elif event == 'Another':
            another_window()