Событие wxNotebook работает только при последней привязке - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть эта программа, которая имеет панель с ноутбуком, которая имеет различные панели. У этих панелей есть некоторый текст, потому что он более конкретен, а затем другая панель, которая предназначена только для построения графиков и является более общей, поскольку я отправляю на панель графиков данные от его родителя. Хорошо, моя проблема в том, что наличие нескольких графиков в реальном времени одновременно замедляет работу приложения.

Я пытаюсь реализовать способ остановки и запуска этих анимаций при смене страниц. Итак, я привязываю и 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))

, если нужен код первой панели (рамки), просто скажите мне.

Так«Я ожидал бы, что если я просматриваю через страницы, живой график текущих страниц останавливается, и живой график текущей страницы начинается, если они уже начались.

1 Ответ

0 голосов
/ 07 ноября 2019

Я продолжаю свое исследование и решил эту проблему, добавив 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 не выполняет работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...