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

Time:12-15

I have a PySimpleGUI window that contains a Matplotlib bar graph. I recently added an event to it that allows the user to click a bar and access a function based on the bar's label. This works great... until I follow up with a click in a non-matplotlib area, such as my PSG buttons. After doing some testing, it appears that this issue only happens if I call a new, different, window function as a result of the on_click event function running. In my example here, if I remove another_window(), I don't have an issue click-printing the names of my bars or hitting buttons in PSG. The problem is that I need to trigger other windows and be able to return to a functioning main window. What am I doing incorrectly? Thanks in advance!

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()

CodePudding user response:

Not sure what's wrong about fig.canvas.mpl_connect. My suggestion is not create a new window in the event handler, but generate an event to main_window for new 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()
  • Related