在 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()
我有一个包含 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.
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()