python - wxNotebook 事件仅在最后一次绑定时起作用
问题描述
我有这个程序,它有一个面板和一个带有各种面板的笔记本。这些面板有一些文本,因为它更具体,然后是另一个面板,它仅用于绘图,因为我将来自他父母的数据发送到绘图面板。好的,我的问题是同时拥有多个实时绘图会使应用程序变慢。
我正在尝试实现一种在通过页面更改时停止和启动这些动画的方法。所以'我wx.EVT_NOTEBOOK_PAGE_CHANGED
在大型机的面板中绑定了一个方法来处理动画的停止和开始。但是当我尝试这个时,唯一执行的绑定只是最后一个,前两个不会触发它们自己。同样在这种方法中,我试图知道女巫是当前页面,女巫是选定的页面,所以选定的页面接收事件开始,当前接收事件并停止。
我尝试在页面中绑定事件,以便所有页面都得到它但没有运气,还尝试通过在面板中创建一个调用 stop 方法并将事件传递给绘图的方法。
这是绘图面板
class live_panel_2(wx.Panel):
def __init__(self, parent):
super(live_panel_2, self).__init__(parent)
sns.set()
self.parent = parent
self.x_axis = []
self.x2_axis = []
self.y_axis = []
self.y2_axis = []
self.line_width = 1
self.flag = False
self.flag1 = False
self.figure = Figure(figsize=(15.5, 3))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axis = self.figure.add_subplot(1, 1, 1)
self.axis2 = self.axis.twinx()
self.toolbar = NavigationToolbar(self.canvas)
self.toolbar.Realize()
#self.button = wx.Button(self, label='Stop')
self.figure.subplots_adjust(left=0.09, right=0.92, top=0.92, bottom=0.2, wspace=1)
self.axis.format_xdata = mdates.DateFormatter('%Y-%m-%d')
#self.axis.tick_params(axis='x', direction='inout', length=5, labelrotation=0)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas, 0, wx.EXPAND, 5 )
sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND, 5)
#sizer.Add(self.button, 0, wx.ALL, 5)
self.SetSizerAndFit(sizer)
self.Bind(wx.EVT_CLOSE, self.stop)
self.canvas.draw()
#self.Bind(wx.EVT_BUTTON, self.stop, self.button)
#self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.page_stop, parent.parent)
def build(self, model, model_2, y, y2, delta, localization):
if self.flag1:
self.ani._stop()
self.x_axis = []
self.x2_axis = []
self.y_axis = []
self.y2_axis = []
self.delta = delta
self.ani = animation.FuncAnimation(self.figure, self.animate,
fargs=(self.x_axis, self.x2_axis, self.y_axis, self.y2_axis, model, model_2, y, y2, localization), interval=500)
self.flag1 = True
self.ani._start()
def close(self):
self.ani._stop()
def stop(self, event):
if self.parent == self.parent.parent.GetCurrentPage():
if self.flag == False and self.flag1 == True:
self.ani.event_source.stop()
self.flag = True
self.button.SetLabel('Start')
elif self.flag == True and self.flag1 == True:
self.ani.event_source.start()
self.flag = False
self.button.SetLabel('Stop')
#Animation
def animate(self, i, x_axis, x2_axis, y_axis, y2_axis, model, model2, y, y2, localization):
#Data query
self.now = datetime.now()
self.now_delta = self.now - timedelta(minutes=self.delta)
if not self.x_axis:
with session_scope() as s:
value = s.query(y).order_by(model.Datetime.desc()).filter(model.Datetime < self.now).filter(model.Datetime > self.now_delta).all()
value2 = s.query(y2).order_by(model2.Datetime.desc()).filter(model2.Datetime > self.now_delta).filter(model2.Datetime < self.now).all()
time = s.query(model.Datetime).order_by(model.Datetime.desc()).filter(model.Datetime > self.now_delta).filter(model.Datetime < self.now).all()
time2 = s.query(model2.Datetime).order_by(model2.Datetime.desc()).filter(model2.Datetime > self.now_delta).filter(model2.Datetime < self.now).all()
for i in reversed(value):
self.y_axis.append(i[0])
for i in reversed(value2):
self.y2_axis.append(i[0])
for i in reversed(time):
self.x_axis.append(i[0])
for i in reversed(time2):
self.x2_axis.append(i[0])
if self.x_axis:
with session_scope() as s:
# value = s.query(y).order_by(model.Datetime.desc()).first()
# value2 = s.query(y2).order_by(model2.Datetime.desc()).first()
# time = s.query(model.Datetime).order_by(model.Datetime.desc()).first()
# time2 = s.query(model2.Datetime).order_by(model2.Datetime.desc()).first()
value = s.query(y).filter(model.Datetime > self.x_axis[-1]).all()
value2 = s.query(y2).filter(model2.Datetime > self.x2_axis[-1]).all()
time = s.query(model.Datetime).filter(model.Datetime > self.x_axis[-1]).all()
time2 = s.query(model2.Datetime).filter(model2.Datetime > self.x2_axis[-1]).all()
# if type(time) != type(None) and type(value) != type(None):
# time = time[0]
# time2 = time2[0]
# value = round(value[0], 2)
# value2 = round(value2[0], 2)
for i in value:
self.y_axis.append(i[0])
for i in value2:
self.y2_axis.append(i[0])
for i in time:
self.x_axis.append(i[0])
for i in time2:
self.x2_axis.append(i[0])
# x_axis.append(time)
# x2_axis.append(time2)
# y_axis.append(value)
# y2_axis.append(value2)
if len(x_axis) < len(y_axis):
delta = len(y_axis) - len(x_axis)
y_axis = y_axis[:-delta]
elif len(x_axis) > len(y_axis):
delta = len(x_axis) - len(y_axis)
x_axis = x_axis[:-delta]
if len(x2_axis) < len(y2_axis):
delta = len(y2_axis) - len(x2_axis)
y_axis = y_axis[:-delta]
elif len(x2_axis) > len(y2_axis):
delta = len(x2_axis) - len(y2_axis)
x2_axis = x2_axis[:-delta]
#Capacity of points
x_axis = x_axis[-self.delta*60:]
x2_axis = x2_axis[-self.delta*60:]
y_axis = y_axis[-self.delta*60:]
y2_axis = y2_axis[-self.delta*60:]
#Clear Axis
self.axis.clear()
self.axis2.clear()
#Set axis 2 format
self.axis.set_title(model.Datetime.name + ' vs ' + y.name + ' vs ' + y2.name)
self.axis.set_xlim(min(x_axis), max(x_axis))
self.axis.set_xlabel(model.Datetime.name)
self.axis.set_ylabel(y.name)
line_1 = self.axis.plot(x_axis, y_axis, linewidth=self.line_width, label=y.name)
# self.axis.annotate(str(value), xy=(time, value), xytext=(10, -2), textcoords='offset pixels',
# bbox=dict(boxstyle=custom_box_style, alpha=0.2))
#Set Axis 2 Format
self.axis2.set_xlim(min(x2_axis), max(x2_axis))
self.axis2.set_xlabel(model.Datetime.name)
self.axis2.set_ylabel(y2.name)
line_2 = self.axis2.plot(x2_axis, y2_axis, linewidth=self.line_width, color='G', label=y2.name)
# self.axis2.annotate(str(value2), xy=(time, value2), xytext=(10, -2), textcoords='offset pixels',
# bbox=dict(boxstyle=custom_box_style, alpha=0.2))
#Get lines and labels for legends
lines = line_1 + line_2
labels = [l.get_label() for l in lines]
#Turn of scientific notation
self.axis.yaxis.set_major_formatter(mticker.ScalarFormatter())
self.axis.yaxis.get_major_formatter().set_scientific(False)
self.axis.yaxis.get_major_formatter().set_useOffset(False)
self.axis2.yaxis.set_major_formatter(mticker.ScalarFormatter())
self.axis2.yaxis.get_major_formatter().set_scientific(False)
self.axis2.yaxis.get_major_formatter().set_useOffset(False)
#Set legend and turn axes 2 grid off
self.axis2.legend(lines, labels, loc=localization)
self.axis2.grid(False)
# Format plot
self.figure.canvas.mpl_connect('close_event', self.close)
#tm.sleep(1)
这是仪表板。
class ccn(scrolled.ScrolledPanel):
def __init__(self, parent, title):
super(ccn, self).__init__(parent, name=title)
self.parent = parent
self.visa = visa_instruments()
self.SetupScrolling()
locations = ['Best', 'Upper left', 'Upper right', 'Lower left', 'Lower right', 'Center', 'Upper center',
'Lower center', 'Center left', 'Center right']
EVT_RESULT(self, self.update_display)
mainsizer = wx.BoxSizer(wx.VERTICAL)
current_ss_sizer = wx.BoxSizer(wx.HORIZONTAL)
stage_sizer = wx.BoxSizer(wx.HORIZONTAL)
concentration_sizer = wx.BoxSizer(wx.HORIZONTAL)
data_header = wx.StaticBoxSizer(wx.VERTICAL, self, label='Data:')
plot_border = wx.StaticBoxSizer(wx.VERTICAL, self, label='Live Plot')
plot_selector_sizer = wx.BoxSizer(wx.HORIZONTAL)
delta_sizer = wx.BoxSizer(wx.HORIZONTAL)
cmd_sizer = wx.BoxSizer(wx.HORIZONTAL)
gmd_sizer = wx.BoxSizer(wx.HORIZONTAL)
variable_1 = wx.StaticText(self, label='Variable 1: ')
variable_2 = wx.StaticText(self, label='Variable 2: ')
time_scale = wx.StaticText(self, label='Time Scale(min): ')
leyend_location_text = wx.StaticText(self, label='Leyend Location: ')
current_ss_text = wx.StaticText(self, label='Current SS:')
first_stage_text = wx.StaticText(self, label='First Stage Mon(V):')
concentration_text = wx.StaticText(self, label='CCN Number Concentration(#/m^3):')
delta_text = wx.StaticText(self, label='Delta T(C): ')
cmd_text = wx.StaticText(self, label='CMD: ')
gmd_text = wx.StaticText(self, label='GMD: ')
self.current_ss_value = wx.StaticText(self, label='N/A')
self.stage_value = wx.StaticText(self, label='N/A')
self.concentration_value = wx.StaticText(self, label='N/A')
self.delta_value = wx.StaticText(self, label='N/A')
self.cmd_value = wx.StaticText(self, label='N/A')
self.gmd_values = wx.StaticText(self, label='N/A')
self.plot = live_panel_2(self)
self.x_data_selector = wx.ComboBox(self, value='X-Axis Data')
self.y_data_selector = wx.ComboBox(self, value='Y-Axis Data')
self.time_scale = wx.ComboBox(self, value='Time Scale', size=(80, -1))
self.button = wx.Button(self, label='Enter')
self.leyend_location_selector = wx.ComboBox(self)
self.leyend_location_selector.Append(locations)
time_range = range(60)
for i in time_range:
self.time_scale.Append(str(i+1), i+1)
current_ss_sizer.Add(current_ss_text, 0, wx.ALL, 5)
current_ss_sizer.Add(self.current_ss_value, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
concentration_sizer.Add(concentration_text, 0, wx.ALL, 5)
concentration_sizer.Add(self.concentration_value, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
stage_sizer.Add(first_stage_text, 0, wx.ALL, 5)
stage_sizer.Add(self.stage_value, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
delta_sizer.Add(delta_text, 0, wx.ALL, 5)
delta_sizer.Add(self.delta_value, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
cmd_sizer.Add(cmd_text, 0, wx.ALL, 5)
cmd_sizer.Add(self.cmd_value, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
gmd_sizer.Add(gmd_text, 0, wx.ALL, 5)
gmd_sizer.Add(self.gmd_values, 0, wx.ALL|wx.ALIGN_RIGHT, 5)
data_header.Add(current_ss_sizer, 0, wx.ALL, 5)
data_header.Add(stage_sizer, 0, wx.ALL, 5)
data_header.Add(concentration_sizer, 0, wx.ALL, 5)
data_header.Add(delta_sizer, 0, wx.ALL, 5)
data_header.Add(cmd_sizer, 0, wx.ALL, 5)
data_header.Add(gmd_sizer, 0, wx.ALL, 5)
plot_selector_sizer.Add(variable_1, 0, wx.ALL, 5)
plot_selector_sizer.Add(self.x_data_selector, 0, wx.ALL, 5)
plot_selector_sizer.Add(variable_2, 0, wx.ALL, 5)
plot_selector_sizer.Add(self.y_data_selector, 0, wx.ALL, 5)
plot_selector_sizer.Add(time_scale, 0, wx.ALL, 5)
plot_selector_sizer.Add(self.time_scale, 0, wx.ALL, 5)
plot_selector_sizer.Add(leyend_location_text, 0, wx.ALL, 5)
plot_selector_sizer.Add(self.leyend_location_selector, 0, wx.ALL, 5)
plot_selector_sizer.Add(self.button, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
plot_border.Add(plot_selector_sizer, 0, wx.ALL, 5)
plot_border.Add(self.plot, 0, wx.ALL, 5)
mainsizer.Add(data_header,0,wx.ALL|wx.EXPAND,5)
mainsizer.Add(plot_border,0,wx.ALL|wx.EXPAND,5)
#mainsizer.Add(self.logbox, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizeHints(200, 10, 700, 700) # SetSizeHints(minW, minH, maxW, maxH)
self.SetSizerAndFit(mainsizer)
DataThread(self)
#logupdater(self.logbox)
self.x_selector(wx.EVT_BUTTON)
self.Bind(wx.EVT_CLOSE, self.stop)
self.Bind(wx.EVT_BUTTON, self.builder, self.button)
#self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.plot.stop, self.parent)
def stop_plot(self, event):
self.plot.stop(event)
def builder(self, event):
x_selection = self.x_data_selector.GetCurrentSelection()
y_selection = self.y_data_selector.GetCurrentSelection()
model = ccn_model
y = self.x_data_selector.GetClientObject(x_selection)
y2 = self.y_data_selector.GetClientObject(y_selection)
location = self.leyend_location_selector.GetStringSelection().lower()
delta = self.time_scale.GetStringSelection()
self.plot.build(model, model, y, y2, int(delta), location)
def x_selector(self, event):
model = ccn_model
self.x_data_selector.Clear()
columns = model_columns(model)
for i in columns:
if i[0] != 'Datetime':
self.x_data_selector.Append(i[0], i[1])
self.y_selector(model)
def y_selector(self, model):
self.y_data_selector.Clear()
columns = model_columns(model)
for i in columns:
if i[0] != 'Datetime':
self.y_data_selector.Append(i[0], i[1])
def stop(self, event):
self.Destroy()
def update_display(self, data):
if type(data) is not type(None):
if self.current_ss_value:
self.current_ss_value.SetLabel(str(data.Current_ss))
if self.stage_value:
self.stage_value.SetLabel(str(data.first_Stage_Mon))
if self.concentration_value:
self.concentration_value.SetLabel(str(data.CCN_Number_Conc))
if self.delta_value:
self.delta_value.SetLabel(str(data.Delta_T))
if self.cmd_value:
self.cmd_value.SetLabel(str(data.CMD))
if self.gmd_values:
self.gmd_values.SetLabel(str(data.GMD))
如果需要第一个面板(框架)的代码,请告诉我。
所以'我希望,如果我正在浏览页面,则当前页面的实时图会停止,如果它们已经开始,我将要开始的页面的实时图会开始。
解决方案
我继续我的研究,并通过event.skip
在方法末尾添加来解决这个问题。
def stop(self, event):
if self.ani:
if self.flag == False and self.flag1 == True and self.parent != self.parent.parent.GetCurrentPage():
self.ani.event_source.stop()
self.flag = True
#self.button.SetLabel('Start')
elif self.flag == True and self.flag1 == True and self.parent == self.parent.parent.GetCurrentPage():
self.ani.event_source.start()
self.flag = False
#self.button.SetLabel('Stop')
event.Skip()
还研究了逻辑,但如果我没有在面板中开始实时绘图,我会收到
Traceback (most recent call last):
File "C:\Users\ACAS\PycharmProjects\ACAS\Main\GUI\plotter.py", line 172, in stop
if self.ani:
AttributeError: 'live_panel_2' object has no attribute 'ani'
我想检查是否self.ani
存在但 if 不做工作。
推荐阅读
- swift - 如何从 Pod 框架中删除 UIWebView?
- mysql - 您如何使用 discord.js mysql 检查该 ID 的数据是否已存在
- java - Java根据交付ID在国际交付列表中升序排序
- c++ - C ++从字符串制作特定的字符
- ios - 如何确定 iOS 设备的视频播放能力?
- awk - sed 或 awk:替换为先前出现的计数
- apache-kafka - 我可以在 Kafka Stream Topology 中多次使用主题吗?
- javascript - v-for 循环不适用于数组项
- objective-c - 如何控制 DataElement 中 SegmentedControl 的外观
- javascript - Angular 9 + Firebase。更新数据库中的属性