Beispiel #1
0
 def __init__(self, parent, data_file):
     self.parent = parent
     self.data_file = data_file
     self.controller = PlotWindowController(self, data_file)
     module_logger.info("Successfully initialized PlotWindow.")
     self.load_data()
 def __init__(self, parent, data_file):
     self.parent = parent
     self.data_file = data_file
     self.controller = PlotWindowController(self, data_file)
     module_logger.info("Successfully initialized PlotWindow.")
     self.load_data()
Beispiel #3
0
class PlotWindow(wx.Frame):
    """Basic wxPython UI element for displaying matplotlib plots"""
    def __init__(self, parent, data_file):
        self.parent = parent
        self.data_file = data_file
        self.controller = PlotWindowController(self, data_file)
        module_logger.info("Successfully initialized PlotWindow.")
        self.load_data()

    def has_data(self):
        """Returns True if data is not None"""
        return self.controller.data is not None

    def load_data(self):
        """Loads the data set and plots"""
        exception_queue = Queue.Queue()
        data_thd = workerthread.WorkerThread(exception_queue=exception_queue,
                                             target=self.controller.load_data)
        data_thd.start()
        while True:
            data_thd.join(0.125)
            if not data_thd.is_alive():
                try:
                    exc_type, exc = exception_queue.get(block=False)
                    err_str = str(exc)
                    if len(err_str) == 0:
                        err_str = exc_type.__name__
                    module_logger.error(
                        "Unable to load data: {0}".format(err_str))
                    err_msg = "An error occurred while loading data:\n{0}".format(
                        err_str)
                    if len(err_msg) > 150:
                        # Truncate lengthy error messages
                        err_msg = ''.join([err_msg[:150], "\n(continued)"])
                    err_dlg = wx.MessageDialog(self.parent,
                                               message=err_msg,
                                               caption="Unable To Load Data",
                                               style=wx.ICON_ERROR)
                    err_dlg.ShowModal()
                except Queue.Empty:
                    pass
                break
            wx.GetApp().Yield(True)
        if self.has_data():
            self.title = 'Plot - {0}'.format(os.path.basename(self.data_file))
            wx.Frame.__init__(self,
                              id=wx.ID_ANY,
                              parent=self.parent,
                              title=self.title)
            self.init_menu()
            self.init_ui()
            self.controller.plot(self.controller.data)

    def init_ui(self):
        """Creates the PlotWindow UI"""
        parent_x, parent_y = self.parent.GetPositionTuple()
        parent_w, parent_h = self.parent.GetSize()
        self.SetPosition((parent_x + parent_w + ui_defaults.widget_margin,
                          ui_defaults.widget_margin))
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.figure = Figure(figsize=(5, 4))
        self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure)
        self.axes = self.figure.add_subplot(111, picker=True)
        self.axes.grid(True)
        #self.cursor = Cursor(self.axes, useblit=True, color='green', alpha=0.5, linestyle='--',
        # linewidth=2)
        self.sizer.Add(self.canvas, 1, ui_defaults.sizer_flags, 0)
        self.add_toolbar()
        self.SetIcon(self.parent.GetIcon())
        self.SetSizerAndFit(self.sizer)

    def add_toolbar(self):
        """Creates the matplotlib toolbar (zoom, pan/scroll, etc.)
        for the plot"""
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if wx.Platform == '__WXMAC__':
            self.SetToolBar(self.toolbar)
        else:
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND, 0)
        self.toolbar.update()

    def init_menu(self):
        """Creates the main menu"""
        self.menubar = wx.MenuBar()
        self.init_file_menu()
        self.init_plot_menu()
        self.init_ops_menu()
        self.init_tools_menu()
        self.init_help_menu()
        self.SetMenuBar(self.menubar)

    def init_file_menu(self):
        """Creates the File menu"""
        self.file_mnu = wx.Menu()
        savedata_mnui = wx.MenuItem(self.file_mnu,
                                    wx.ID_ANY,
                                    text="Save Current Data",
                                    help="Save current data to disk")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_save_data,
                  id=savedata_mnui.GetId())
        self.file_mnu.AppendItem(savedata_mnui)
        close_mnui = wx.MenuItem(self.file_mnu,
                                 wx.ID_ANY,
                                 text="Close Window",
                                 help="Close the plot window")
        self.Bind(wx.EVT_MENU, self.controller.on_close, id=close_mnui.GetId())
        self.file_mnu.AppendItem(close_mnui)
        self.menubar.Append(self.file_mnu, "&File")

    def init_plot_menu(self):
        """Creates the Plot menu"""
        self.plot_mnu = wx.Menu()

        self.labels_mnu = wx.Menu()  # Titles and Labels
        plottitle_mnui = wx.MenuItem(self.labels_mnu,
                                     wx.ID_ANY,
                                     text="Set Plot Title",
                                     help="Set Plot Title")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_set_plottitle,
                  id=plottitle_mnui.GetId())
        self.labels_mnu.AppendItem(plottitle_mnui)
        xlbl_mnui = wx.MenuItem(self.labels_mnu,
                                wx.ID_ANY,
                                text="Set X Axis Label",
                                help="Set X Axis Label")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_set_xlabel,
                  id=xlbl_mnui.GetId())
        self.labels_mnu.AppendItem(xlbl_mnui)
        ylbl_mnui = wx.MenuItem(self.labels_mnu,
                                wx.ID_ANY,
                                text="Set Y Axis Label",
                                help="Set Y Axis Label")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_set_ylabel,
                  id=ylbl_mnui.GetId())
        self.labels_mnu.AppendItem(ylbl_mnui)
        self.plot_mnu.AppendMenu(wx.ID_ANY, 'Title And Labels',
                                 self.labels_mnu)

        gridtoggle_mnui = wx.MenuItem(self.plot_mnu,
                                      wx.ID_ANY,
                                      text="Toggle Grid",
                                      help="Turns grid on or off")
        self.plot_mnu.AppendItem(gridtoggle_mnui)
        self.Bind(wx.EVT_MENU,
                  self.controller.on_toggle_grid,
                  id=gridtoggle_mnui.GetId())
        self.menubar.Append(self.plot_mnu, "&Plot")

    def init_ops_menu(self):
        """Creates the Operations menu"""
        self.ops_mnu = wx.Menu()
        self.revert_mnui = wx.MenuItem(self.ops_mnu,
                                       wx.ID_ANY,
                                       text='Revert To Original',
                                       help='Revert to original data set')
        self.Bind(wx.EVT_MENU,
                  self.controller.on_revert,
                  id=self.revert_mnui.GetId())
        self.ops_mnu.AppendItem(self.revert_mnui)
        self.init_specific_ops_menu()
        self.menubar.Append(self.ops_mnu, '&Operations')

    def init_specific_ops_menu(self):
        """Creates any plot-specific Operations menu items"""
        self.rect_mnu = wx.Menu()  # Rectification operations
        self.fullrect_mnui = wx.MenuItem(self.rect_mnu,
                                         wx.ID_ANY,
                                         text="Full",
                                         help="Full Rectification")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_rectify,
                  id=self.fullrect_mnui.GetId())
        self.rect_mnu.AppendItem(self.fullrect_mnui)
        self.ops_mnu.AppendMenu(wx.ID_ANY, 'Rectify', self.rect_mnu)

        self.gate_mnu = wx.Menu()  # Gates operations
        for gate in self.controller.gates:
            gate_name = self.controller.gates[gate][0]
            gate_desc = "Applies a {0} gate function to the data".format(
                gate_name)
            gate_mnui = wx.MenuItem(self.gate_mnu,
                                    id=gate,
                                    text=gate_name,
                                    help=gate_desc)
            self.gate_mnu.AppendItem(gate_mnui)
            self.Bind(wx.EVT_MENU,
                      self.controller.on_apply_gate,
                      id=gate_mnui.GetId())
        self.ops_mnu.AppendMenu(wx.ID_ANY, 'Gates', self.gate_mnu)

    def init_tools_menu(self):
        """Initializes the Tools Menu (Plugins and external scripts)"""
        self.tools_mnu = wx.Menu()
        self.init_plugins_menu()
        self.menubar.Append(self.tools_mnu, '&Tools')

    def init_plugins_menu(self):
        """Initializes the Plugins menu"""
        # If the Plugins menu already exists,
        # delete and rebuild.  Used to refresh
        # list of available plugins after installing
        # a new one
        plugins_mnu_id = self.tools_mnu.FindItem("Plugins")
        if plugins_mnu_id != -1:
            self.tools_mnu.RemoveItem(
                self.tools_mnu.FindItemById(plugins_mnu_id))
        self.plugins_mnu = wx.Menu()
        plugins = self.controller.available_plugins
        for plugin_id, plugin in plugins.items():
            plugin_name = plugin[1].name
            plugin_description = plugin[1].description
            script_mnui = wx.MenuItem(self.tools_mnu,
                                      id=plugin_id,
                                      text=plugin_name,
                                      help=plugin_description)
            self.Bind(wx.EVT_MENU,
                      self.controller.on_run_toolkit,
                      id=script_mnui.GetId())
            self.plugins_mnu.AppendItem(script_mnui)
        self.plugins_mnu.AppendSeparator()
        install_plugin_mnui = wx.MenuItem(self.plugins_mnu,
                                          wx.ID_ANY,
                                          text="Install Plugin...",
                                          help="Install a local plugin")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_install_plugin,
                  id=install_plugin_mnui.GetId())
        self.plugins_mnu.AppendItem(install_plugin_mnui)
        download_plugin_mnui = wx.MenuItem(
            self.plugins_mnu,
            wx.ID_ANY,
            text="Download Plugin...",
            help="Download and install a new plugin")
        self.Bind(wx.EVT_MENU,
                  self.controller.on_download_plugin,
                  id=download_plugin_mnui.GetId())
        self.plugins_mnu.AppendItem(download_plugin_mnui)
        self.tools_mnu.AppendMenu(wx.ID_ANY, "Plugins", self.plugins_mnu)

    def init_help_menu(self):
        pass
class PlotWindow(wx.Frame):
    """Basic wxPython UI element for displaying matplotlib plots"""

    def __init__(self, parent, data_file):
        self.parent = parent
        self.data_file = data_file
        self.controller = PlotWindowController(self, data_file)
        module_logger.info("Successfully initialized PlotWindow.")
        self.load_data()

    def has_data(self):
        """Returns True if data is not None"""
        return self.controller.data is not None

    def load_data(self):
        """Loads the data set and plots"""
        exception_queue = Queue.Queue()
        data_thd = workerthread.WorkerThread(exception_queue=exception_queue,
                                             target=self.controller.load_data)
        data_thd.start()
        while True:
            data_thd.join(0.125)
            if not data_thd.is_alive():
                try:
                    exc_type, exc = exception_queue.get(block=False)
                    err_str = str(exc)
                    if len(err_str) == 0:
                        err_str = exc_type.__name__
                    module_logger.error("Unable to load data: {0}".format(err_str))
                    err_msg = "An error occurred while loading data:\n{0}".format(err_str)
                    if len(err_msg) > 150:
                        # Truncate lengthy error messages
                        err_msg = ''.join([err_msg[:150], "\n(continued)"])
                    err_dlg = wx.MessageDialog(self.parent, message=err_msg,
                                               caption="Unable To Load Data", style=wx.ICON_ERROR)
                    err_dlg.ShowModal()
                except Queue.Empty:
                    pass
                break
            wx.GetApp().Yield(True)
        if self.has_data():
            self.title = 'Plot - {0}'.format(os.path.basename(self.data_file))
            wx.Frame.__init__(self, id=wx.ID_ANY, parent=self.parent, title=self.title)
            self.init_menu()
            self.init_ui()
            self.controller.plot(self.controller.data)

    def init_ui(self):
        """Creates the PlotWindow UI"""
        parent_x, parent_y = self.parent.GetPositionTuple()
        parent_w, parent_h = self.parent.GetSize()
        self.SetPosition((parent_x + parent_w + ui_defaults.widget_margin,
                          ui_defaults.widget_margin))
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.figure = Figure(figsize=(5, 4))
        self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure)
        self.axes = self.figure.add_subplot(111, picker=True)
        self.axes.grid(True)
        #self.cursor = Cursor(self.axes, useblit=True, color='green', alpha=0.5, linestyle='--',
        # linewidth=2)
        self.sizer.Add(self.canvas, 1, ui_defaults.sizer_flags, 0)
        self.add_toolbar()
        self.SetIcon(self.parent.GetIcon())
        self.SetSizerAndFit(self.sizer)

    def add_toolbar(self):
        """Creates the matplotlib toolbar (zoom, pan/scroll, etc.)
        for the plot"""
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if wx.Platform == '__WXMAC__':
            self.SetToolBar(self.toolbar)
        else:
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND, 0)
        self.toolbar.update()

    def init_menu(self):
        """Creates the main menu"""
        self.menubar = wx.MenuBar()
        self.init_file_menu()
        self.init_plot_menu()
        self.init_ops_menu()
        self.init_tools_menu()
        self.init_help_menu()
        self.SetMenuBar(self.menubar)

    def init_file_menu(self):
        """Creates the File menu"""
        self.file_mnu = wx.Menu()
        savedata_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Save Current Data",
                                    help="Save current data to disk")
        self.Bind(wx.EVT_MENU, self.controller.on_save_data, id=savedata_mnui.GetId())
        self.file_mnu.AppendItem(savedata_mnui)
        close_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Close Window",
                                 help="Close the plot window")
        self.Bind(wx.EVT_MENU, self.controller.on_close, id=close_mnui.GetId())
        self.file_mnu.AppendItem(close_mnui)
        self.menubar.Append(self.file_mnu, "&File")

    def init_plot_menu(self):
        """Creates the Plot menu"""
        self.plot_mnu = wx.Menu()

        self.labels_mnu = wx.Menu() # Titles and Labels
        plottitle_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Plot Title",
                                     help="Set Plot Title")
        self.Bind(wx.EVT_MENU, self.controller.on_set_plottitle, id=plottitle_mnui.GetId())
        self.labels_mnu.AppendItem(plottitle_mnui)
        xlbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set X Axis Label",
                                help="Set X Axis Label")
        self.Bind(wx.EVT_MENU, self.controller.on_set_xlabel, id=xlbl_mnui.GetId())
        self.labels_mnu.AppendItem(xlbl_mnui)
        ylbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Y Axis Label",
                                help="Set Y Axis Label")
        self.Bind(wx.EVT_MENU, self.controller.on_set_ylabel, id=ylbl_mnui.GetId())
        self.labels_mnu.AppendItem(ylbl_mnui)
        self.plot_mnu.AppendMenu(wx.ID_ANY, 'Title And Labels', self.labels_mnu)

        gridtoggle_mnui = wx.MenuItem(self.plot_mnu, wx.ID_ANY, text="Toggle Grid",
                                      help="Turns grid on or off")
        self.plot_mnu.AppendItem(gridtoggle_mnui)
        self.Bind(wx.EVT_MENU, self.controller.on_toggle_grid, id=gridtoggle_mnui.GetId())
        self.menubar.Append(self.plot_mnu, "&Plot")

    def init_ops_menu(self):
        """Creates the Operations menu"""
        self.ops_mnu = wx.Menu()
        self.revert_mnui = wx.MenuItem(self.ops_mnu, wx.ID_ANY, text='Revert To Original',
                                       help='Revert to original data set')
        self.Bind(wx.EVT_MENU, self.controller.on_revert, id=self.revert_mnui.GetId())
        self.ops_mnu.AppendItem(self.revert_mnui)
        self.init_specific_ops_menu()
        self.menubar.Append(self.ops_mnu, '&Operations')

    def init_specific_ops_menu(self):
        """Creates any plot-specific Operations menu items"""
        self.rect_mnu = wx.Menu() # Rectification operations
        self.fullrect_mnui = wx.MenuItem(self.rect_mnu, wx.ID_ANY, text="Full",
                                         help="Full Rectification")
        self.Bind(wx.EVT_MENU, self.controller.on_rectify, id=self.fullrect_mnui.GetId())
        self.rect_mnu.AppendItem(self.fullrect_mnui)
        self.ops_mnu.AppendMenu(wx.ID_ANY, 'Rectify', self.rect_mnu)

        self.gate_mnu = wx.Menu() # Gates operations
        for gate in self.controller.gates:
            gate_name = self.controller.gates[gate][0]
            gate_desc = "Applies a {0} gate function to the data".format(gate_name)
            gate_mnui = wx.MenuItem(self.gate_mnu, id=gate, text=gate_name, help=gate_desc)
            self.gate_mnu.AppendItem(gate_mnui)
            self.Bind(wx.EVT_MENU, self.controller.on_apply_gate, id=gate_mnui.GetId())
        self.ops_mnu.AppendMenu(wx.ID_ANY, 'Gates', self.gate_mnu)

    def init_tools_menu(self):
        """Initializes the Tools Menu (Plugins and external scripts)"""
        self.tools_mnu = wx.Menu()
        self.init_plugins_menu()
        self.menubar.Append(self.tools_mnu, '&Tools')

    def init_plugins_menu(self):
        """Initializes the Plugins menu"""
        # If the Plugins menu already exists,
        # delete and rebuild.  Used to refresh
        # list of available plugins after installing
        # a new one
        plugins_mnu_id = self.tools_mnu.FindItem("Plugins")
        if plugins_mnu_id != -1:
            self.tools_mnu.RemoveItem(self.tools_mnu.FindItemById(plugins_mnu_id))
        self.plugins_mnu = wx.Menu()
        plugins = self.controller.available_plugins
        for plugin_id, plugin in plugins.items():
            plugin_name = plugin[1].name
            plugin_description = plugin[1].description
            script_mnui = wx.MenuItem(self.tools_mnu, id=plugin_id, text=plugin_name,
                                      help=plugin_description)
            self.Bind(wx.EVT_MENU, self.controller.on_run_toolkit, id=script_mnui.GetId())
            self.plugins_mnu.AppendItem(script_mnui)
        self.plugins_mnu.AppendSeparator()
        install_plugin_mnui = wx.MenuItem(self.plugins_mnu, wx.ID_ANY, text="Install Plugin...",
                                          help="Install a local plugin")
        self.Bind(wx.EVT_MENU, self.controller.on_install_plugin, id=install_plugin_mnui.GetId())
        self.plugins_mnu.AppendItem(install_plugin_mnui)
        download_plugin_mnui = wx.MenuItem(self.plugins_mnu, wx.ID_ANY, text="Download Plugin...",
                                           help="Download and install a new plugin")
        self.Bind(wx.EVT_MENU, self.controller.on_download_plugin, id=download_plugin_mnui.GetId())
        self.plugins_mnu.AppendItem(download_plugin_mnui)
        self.tools_mnu.AppendMenu(wx.ID_ANY, "Plugins", self.plugins_mnu)

    def init_help_menu(self):
        pass