Ejemplo n.º 1
0
    def test_log_window(self):
        log.create_gui_logger(self.frame.txt_log)

        def log_msg():
            for i in xrange(50000):
                random.choice(LOG_FUNCTIONS)("WEEEEEE %d" % i)
                threading._sleep(0.0001)

        t = threading.Thread(target=log_msg)
        # Setting Daemon to True, will cause the thread to exit when the parent does
        t.setDaemon(True)
        t.start()

        test.gui_loop()
Ejemplo n.º 2
0
    def test_log_window(self):
        log.create_gui_logger(self.frame.txt_log)

        def log_msg():
            for i in xrange(50000):
                random.choice(LOG_FUNCTIONS)("WEEEEEE %d" % i)
                threading._sleep(0.0001)

        t = threading.Thread(target=log_msg)
        # Setting Daemon to True, will cause the thread to exit when the parent does
        t.setDaemon(True)
        t.start()

        test.gui_loop()
Ejemplo n.º 3
0
    def init_gui(self):
        """ This method binds events to menu items and initializes GUI controls """

        try:
            # Add frame icon
            ib = wx.IconBundle()
            ib.AddIcon(gui.icon)
            self.main_frame.SetIcons(ib)
            self.main_frame.SetTitle(gui.name)

            # IMPORTANT NOTE:
            # As all tab panels are hidden on start-up, the MinSize attribute
            # of the main GUI frame will be set to such a low value that most of
            # the interface will be invisible if the user takes the interface out of
            # 'full screen' view.
            # Also, Gnome's GDK library will start spewing error messages, saying
            # it cannot draw certain images, because the dimensions are 0x0.
            self.main_frame.SetMinSize((1000, 550))
            self.main_frame.Maximize()  # must be done before Show()

            # List of all possible tabs used in Odemis' main GUI
            tab_defs = [
                {
                    # Unique name of the tab
                    "name": "secom_live",
                    # Tab controller for this tab
                    "controller": tabs.SecomStreamsTab,
                    # Tab button for this tab
                    "button": self.main_frame.btn_tab_secom_streams,
                    # Constructor of the tab panel
                    "panel": main_xrc.xrcpnl_tab_secom_streams
                },
                {
                    "name": "cryosecom-localization",
                    "controller": tabs.LocalizationTab,
                    "button": self.main_frame.btn_tab_localization,
                    "panel": main_xrc.xrcpnl_tab_localization
                },
                {
                    "name": "secom_align",
                    "controller": tabs.SecomAlignTab,
                    "button": self.main_frame.btn_tab_align,
                    "panel": main_xrc.xrcpnl_tab_secom_align
                },
                {
                    "name": "sparc_align",
                    "controller": tabs.SparcAlignTab,
                    "button": self.main_frame.btn_tab_align,
                    "panel": main_xrc.xrcpnl_tab_sparc_align
                },
                {
                    "name": "sparc2_align",
                    "controller": tabs.Sparc2AlignTab,
                    "button": self.main_frame.btn_tab_align,
                    "panel": main_xrc.xrcpnl_tab_sparc2_align
                },
                {
                    "name": "sparc_acqui",
                    "controller": tabs.SparcAcquisitionTab,
                    "button": self.main_frame.btn_tab_sparc_acqui,
                    "panel": main_xrc.xrcpnl_tab_sparc_acqui
                },
                {
                    "name": "fastem_overview",
                    "controller": tabs.FastEMOverviewTab,
                    "button": self.main_frame.btn_tab_fastem_overview,
                    "panel": main_xrc.xrcpnl_tab_fastem_overview
                },
                {
                    "name": "fastem_acqui",
                    "controller": tabs.FastEMAcquisitionTab,
                    "button": self.main_frame.btn_tab_fastem_acqui,
                    "panel": main_xrc.xrcpnl_tab_fastem_acqui
                },
                {"name": "fastem_chamber",
                    "controller": tabs.FastEMChamberTab,
                    "button": self.main_frame.btn_tab_sparc_chamber,
                    "panel": main_xrc.xrcpnl_tab_fastem_chamber
                },
                {
                    "name": "sparc_chamber",
                    "controller": tabs.ChamberTab,
                    "button": self.main_frame.btn_tab_sparc_chamber,
                    "panel": main_xrc.xrcpnl_tab_sparc_chamber
                },
                {
                    "name": "cryosecom_chamber",
                    "controller": tabs.CryoChamberTab,
                    "button": self.main_frame.btn_tab_cryosecom_chamber,
                    "panel": main_xrc.xrcpnl_tab_cryosecom_chamber
                },
                {
                    "name": "analysis",
                    "controller": tabs.AnalysisTab,
                    "button": self.main_frame.btn_tab_inspection,
                    "panel": main_xrc.xrcpnl_tab_inspection
                },
            ]

            # Create the main tab controller and store a global reference
            # in the odemis.gui.cont package
            self.tab_controller = tabs.TabBarController(tab_defs, self.main_frame, self.main_data)

            # Connect the log panel button of each tab
            def toggle_log_panel(_):
                self.main_data.debug.value = not self.main_frame.pnl_log.IsShown()

            for tab in self.tab_controller.get_tabs():
                if hasattr(tab.panel, 'btn_log'):
                    tab.panel.btn_log.Bind(wx.EVT_BUTTON, toggle_log_panel)
            self.main_frame.btn_log.Bind(wx.EVT_BUTTON, toggle_log_panel)

            self.main_data.debug.subscribe(self.on_debug_va, init=True)
            self.main_data.level.subscribe(self.on_level_va, init=True)
            log.create_gui_logger(self.main_frame.txt_log, self.main_data.debug, self.main_data.level)

            self._menu_controller = MenuController(self.main_data, self.main_frame)
            # Menu events
            self.main_frame.Bind(wx.EVT_MENU, self.on_close_window, id=self.main_frame.menu_item_quit.GetId())

            self.main_frame.Bind(wx.EVT_CLOSE, self.on_close_window)

            # To handle "Save snapshot" menu
            self._snapshot_controller = acquisition.SnapshotController(self.main_data,
                                                                       self.main_frame)

            # Update the logo if a non-default logo is defined
            if gui.logo:
                self.main_frame.logo.SetBitmap(gui.logo)
            # Update legend logo filepath
            self.main_frame.legend_logo = gui.legend_logo

            # Now starts the plugins, after the rest of the GUI is ready
            pfns = plugin.find_plugins()
            for p in pfns:
                pis = plugin.load_plugin(p, self.main_data.microscope, self)
                self.plugins.extend(pis)

            # add temperature controller
            if self.main_data.sample_thermostat:
                self._temperature_controller = TemperatureController(self.main_frame, self.main_data.sample_thermostat)

            # making it very late seems to make it smoother
            wx.CallAfter(self.main_frame.Show)

        except Exception:
            self.excepthook(*sys.exc_info())
            # Re-raise the exception, so the program will exit. If this is not
            # done and exception will prevent the GUI from being shown, while
            # the program keeps running in the background.
            raise
Ejemplo n.º 4
0
class OdemisGUIApp(wx.App):
    """ This is Odemis' main GUI application class
    """

    def __init__(self, standalone=False):
        """
        standalone (boolean): do not try to connect to the backend
        """
        # Replace the standard 'get_resources' with our augmented one, that
        # can handle more control types. See the xhandler package for more info.
        main_xrc.get_resources = odemis_get_resources

        # Declare attributes BEFORE calling the super class constructor
        # because it will call 'OnInit' which uses them.

        # HTTP documentation http server process
        self.http_proc = None

        self.main_data = None
        self.main_frame = None
        self._tab_controller = None
        self._is_standalone = standalone

        if not standalone:
            try:
                driver.speedUpPyroConnect(model.getMicroscope())
            except Exception:
                logging.exception("Failed to speed up start up")

        # Output catcher using a helper class
        wx.App.outputWindowClass = OdemisOutputWindow

        # Constructor of the parent class
        # ONLY CALL IT AT THE END OF :py:method:`__init__` BECAUSE OnInit will
        # be called
        # and it needs the attributes defined in this constructor!
        wx.App.__init__(self, redirect=True)

    def OnInit(self):
        """ Application initialization, automatically run from the :wx:`App`
        constructor.
        """

        if self._is_standalone:
            microscope = None
        else:
            try:
                microscope = model.getMicroscope()
            except (IOError, Pyro4.errors.CommunicationError), e:
                logging.exception("Failed to connect to back-end")
                msg = ("The Odemis GUI could not connect to the Odemis back-end:"
                       "\n\n{0}\n\n"
                       "Launch user interface anyway?").format(e)

                answer = wx.MessageBox(msg,
                                       "Connection error",
                                        style=wx.YES | wx.NO | wx.ICON_ERROR)
                if answer == wx.NO:
                    sys.exit(1)
                microscope = None

        self.main_data = guimodel.MainGUIData(microscope)
        # Load the main frame
        self.main_frame = main_xrc.xrcfr_main(None)

        #self.main_frame.Bind(wx.EVT_CHAR, self.on_key)

        log.create_gui_logger(self.main_frame.txt_log, self.main_data.debug)
        logging.info("\n\n************  Starting Odemis GUI  ************\n")
        logging.info(wx.version())

        self.init_gui()

        # Application successfully launched
        return True
Ejemplo n.º 5
0
    def init_gui(self):
        """ This method binds events to menu items and initializes GUI controls """

        try:
            # Add frame icon
            ib = wx.IconBundle()
            ib.AddIcon(gui.icon)
            self.main_frame.SetIcons(ib)
            self.main_frame.SetTitle(gui.name)

            # IMPORTANT NOTE:
            # As all tab panels are hidden on start-up, the MinSize attribute
            # of the main GUI frame will be set to such a low value that most of
            # the interface will be invisible if the user takes the interface out of
            # 'full screen' view.
            # Also, Gnome's GDK library will start spewing error messages, saying
            # it cannot draw certain images, because the dimensions are 0x0.
            self.main_frame.SetMinSize((1280, 550))
            self.main_frame.Maximize()  # must be done before Show()

            # List of all possible tabs used in Odemis' main GUI

            # TODO: instead of roles + label, have a class method on each
            # StreamTab class that takes the microscope as input, and return a
            # label or None if it shouldn't be displayed. (+ a "priority" to
            # decide which one is the default?)

            tab_defs = [
                {
                    # Unique name of the tab
                    "name": "secom_live",
                    # Tab controller for this tab
                    "controller": tabs.SecomStreamsTab,
                    # Tab button for this tab
                    "button": self.main_frame.btn_tab_secom_streams,
                    # Constructor of the tab panel
                    "panel": main_xrc.xrcpnl_tab_secom_streams
                },
                {
                    "name": "secom_align",
                    "controller": tabs.SecomAlignTab,
                    "button": self.main_frame.btn_tab_secom_align,
                    "panel": main_xrc.xrcpnl_tab_secom_align
                },
                {
                    "name": "sparc_align",
                    "controller": tabs.SparcAlignTab,
                    "button": self.main_frame.btn_tab_sparc_align,
                    "panel": main_xrc.xrcpnl_tab_sparc_align
                },
                {
                    "name": "sparc2_align",
                    "controller": tabs.Sparc2AlignTab,
                    "button": self.main_frame.btn_tab_sparc2_align,
                    "panel": main_xrc.xrcpnl_tab_sparc2_align
                },
                {
                    "name": "sparc_acqui",
                    "controller": tabs.SparcAcquisitionTab,
                    "button": self.main_frame.btn_tab_sparc_acqui,
                    "panel": main_xrc.xrcpnl_tab_sparc_acqui
                },
                {
                    "name": "sparc_chamber",
                    "controller": tabs.ChamberTab,
                    "button": self.main_frame.btn_tab_sparc_chamber,
                    "panel": main_xrc.xrcpnl_tab_sparc_chamber
                },
                {
                    "name": "analysis",
                    "controller": tabs.AnalysisTab,
                    "button": self.main_frame.btn_tab_inspection,
                    "panel": main_xrc.xrcpnl_tab_inspection
                },
            ]

            # Create the main tab controller and store a global reference
            # in the odemis.gui.cont package
            self.tab_controller = tabs.TabBarController(tab_defs, self.main_frame, self.main_data)

            # Connect the log panel button of each tab
            def toggle_log_panel(_):
                self.main_data.debug.value = not self.main_frame.pnl_log.IsShown()

            for tab in self.tab_controller.get_tabs():
                if hasattr(tab.panel, 'btn_log'):
                    tab.panel.btn_log.Bind(wx.EVT_BUTTON, toggle_log_panel)
            self.main_frame.btn_log.Bind(wx.EVT_BUTTON, toggle_log_panel)

            self.main_data.debug.subscribe(self.on_debug_va, init=True)
            self.main_data.level.subscribe(self.on_level_va, init=True)
            log.create_gui_logger(self.main_frame.txt_log, self.main_data.debug, self.main_data.level)

            self._menu_controller = MenuController(self.main_data, self.main_frame)
            # Menu events
            self.main_frame.Bind(wx.EVT_MENU, self.on_close_window, id=self.main_frame.menu_item_quit.GetId())

            self.main_frame.Bind(wx.EVT_CLOSE, self.on_close_window)

            # To handle "Save snapshot" menu
            self._snapshot_controller = acquisition.SnapshotController(self.main_data,
                                                                       self.main_frame)

            # Update the logo if a non-default logo is defined
            if gui.logo:
                self.main_frame.logo.SetBitmap(gui.logo)
            # Update legend logo filepath
            self.main_frame.legend_logo = gui.legend_logo

            # Now starts the plugins, after the rest of the GUI is ready
            pfns = plugin.find_plugins()
            for p in pfns:
                pis = plugin.load_plugin(p, self.main_data.microscope, self)
                self.plugins.extend(pis)

            # making it very late seems to make it smoother
            wx.CallAfter(self.main_frame.Show)

        except Exception:
            self.excepthook(*sys.exc_info())
            # Re-raise the exception, so the program will exit. If this is not
            # done and exception will prevent the GUI from being shown, while
            # the program keeps running in the background.
            raise