Skip to content
Snippets Groups Projects
Commit 08053ee4 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Import problem fixed in actions/about.py (was crashing for non-WX render

tool). Re-worked fsl GUI tool intiailisation so that arguments are
parsed on the wx.MainLoop - trying to get the FSLeyes splash screen
shown ASAP.
parent 08d2a917
No related branches found
No related tags found
No related merge requests found
...@@ -82,10 +82,6 @@ def main(args=None): ...@@ -82,10 +82,6 @@ def main(args=None):
:arg args: Command line arguments. If not provided, ``sys.argv`` is used. :arg args: Command line arguments. If not provided, ``sys.argv`` is used.
""" """
# Search the environment for FSLDIR
fsldir = os.environ.get('FSLDIR', None)
fslEnvActive = fsldir is not None
if args is None: if args is None:
args = sys.argv[1:] args = sys.argv[1:]
...@@ -94,88 +90,118 @@ def main(args=None): ...@@ -94,88 +90,118 @@ def main(args=None):
allTools = _getFSLToolNames() allTools = _getFSLToolNames()
fslTool, namespace, toolArgv = _parseTopLevelArgs(args, allTools) fslTool, namespace, toolArgv = _parseTopLevelArgs(args, allTools)
# If this is a GUI tool, create # GUI or command-line tool?
# the wx application before calling if fslTool.interface is not None: _runGUITool(fslTool, toolArgv)
# fslTool.init(), in case it does else: _runCLITool(fslTool, toolArgv)
# any GUI stuff.
if fslTool.interface is not None:
import wx def _runGUITool(fslTool, toolArgv):
app = wx.App() """Runs the given ``FSLTool``, which is assumed to be a GUI tool.
:arg fslTool: The ``FSLTool`` to run - see the :func:`_loadFSLTool`
function.
:arg toolArgv: Unparsed tool-specific command line arguments.
"""
import wx
fslEnvActive = 'FSLDIR' in os.environ
# Create a wx.App before init(),
# in case it does GUI stuff.
app = wx.App()
# Call the tool's init # Call the tool's init
# function if there is one # function if there is one
if fslTool.init is not None: initVal = fslTool.init() if fslTool.init is not None: initVal = fslTool.init()
else: initVal = None else: initVal = None
# Parse the tool-specific # We are going do all processing on the
# command line arguments # wx.MainLoop, so the GUI can be shown
toolNamespace = _parseToolArgs(fslTool, namespace, toolArgv) # as soon as possible, and because it is
# difficult to force immediate GUI
# refreshes when not running on the main
# loop - this is important for, e.g.
# FSLEyes, which displays status updates
# to the user while it is loading overlays
# and setting up the interface.
#
# To make this work, this buildGUI
# function is called on a separate thread
# (so it is executed after wx.MainLoop
# has been called), but it schedules its
# work to be done on the wx.MainLoop.
def buildGUI():
def realBuild():
# Is this a GUI tool? # Parse the tool-specific
if fslTool.interface is not None: # command line arguments
toolNamespace = _parseToolArgs(fslTool, toolArgv)
import wx # Call the tool context function
if fslTool.context is not None:
ctx = fslTool.context(toolNamespace, initVal)
else:
ctx = None
# The main interface is created on the # Build the GUI
# wx.MainLoop, because it is difficult frame = _buildGUI(toolNamespace, fslTool, ctx, fslEnvActive)
# to force immediate GUI refreshes when frame.Show()
# not running on the main loop - this
# is important for, e.g. FSLEyes, which # See comment about the
# displays status updates to the user # dummy frame below
# while it is loading overlays and dummyFrame.Destroy()
# setting up the interface.
# _fslDirWarning(frame, fslTool.toolName, fslEnvActive)
# To make this work, this buildGUI
# function is called on a separate thread time.sleep(0.1)
# (so it is executed after wx.MainLoop wx.CallAfter(realBuild)
# has been called), but it schedules its
# work to be done on the wx.MainLoop. # Create the wx.App object, and create a dummy
def buildGUI(): # frame. If we don't create a dummy frame, the
def realBuild(): # wx.MainLoop call will just return immediately.
# The buildGUI function above will kill the dummy
if fslTool.context is not None: # frame when it has created the real interface.
ctx = fslTool.context(toolNamespace, initVal) dummyFrame = wx.Frame(None)
else:
ctx = None threading.Thread(target=buildGUI).start()
frame = _buildGUI(toolNamespace, fslTool, ctx, fslEnvActive) # The wx.App was created above,
frame.Show() # before calling fslTool.init()
app.MainLoop()
# See comment below
dummyFrame.Destroy()
def _runCLITool(fslTool, toolArgv):
_fslDirWarning(frame, fslTool.toolName, fslEnvActive) """Runs the given ``FSLTool``, which is assumed to be a command-line (i.e.
non-GUI) tool.
if namespace.wxinspect:
import wx.lib.inspection :arg fslTool: The ``FSLTool`` to run - see the :func:`_loadFSLTool`
wx.lib.inspection.InspectionTool().Show() function.
time.sleep(0.1) :arg toolArgv: Unparsed tool-specific command line arguments.
wx.CallAfter(realBuild) """
# Create the wx.App object, and create a dummy if fslTool.execute is None:
# frame. If we don't create a dummy frame, the return
# wx.MainLoop call will just return immediately.
# The buildGUI function above will kill the dummy # Call the tool's init
# frame when it has created the real interface. # function if there is one
dummyFrame = wx.Frame(None) if fslTool.init is not None: initVal = fslTool.init()
else: initVal = None
threading.Thread(target=buildGUI).start()
# Parse the tool-specific
# The wx.App was created above, # command line arguments
# before calling fslTool.init() namespace = _parseToolArgs(fslTool, toolArgv)
app.MainLoop()
initVal = None
# Or is this a CLI tool? ctx = None
elif fslTool.execute is not None:
if fslTool.init is not None: initVal = fslTool.init()
if fslTool.context is not None: if fslTool.context is not None: ctx = fslTool.context(namespace,
ctx = fslTool.context(toolNamespace, initVal) initVal)
else:
ctx = None
_fslDirWarning(None, fslTool.toolName, fslEnvActive) _fslDirWarning(None, fslTool.toolName, 'FSLDIR' in os.environ)
fslTool.execute(toolNamespace, ctx) fslTool.execute(namespace, ctx)
def runTool(toolName, args, **kwargs): def runTool(toolName, args, **kwargs):
...@@ -343,10 +369,6 @@ def _parseTopLevelArgs(argv, allTools): ...@@ -343,10 +369,6 @@ def _parseTopLevelArgs(argv, allTools):
'-m', '--memory', action='store_true', '-m', '--memory', action='store_true',
help='Output memory events (implied if -v is set)') help='Output memory events (implied if -v is set)')
parser.add_argument(
'-w', '--wxinspect', action='store_true',
help='Run wx inspection tool')
parser.add_argument('tool', help='FSL program to run', nargs='?') parser.add_argument('tool', help='FSL program to run', nargs='?')
# No arguments at all? # No arguments at all?
...@@ -481,16 +503,12 @@ def _parseTopLevelArgs(argv, allTools): ...@@ -481,16 +503,12 @@ def _parseTopLevelArgs(argv, allTools):
return fslTool, namespace, toolArgv return fslTool, namespace, toolArgv
def _parseToolArgs(tool, namespace, argv): def _parseToolArgs(tool, argv):
"""Parses tool-specific command-line arguments. Returns the result of """Parses tool-specific command-line arguments. Returns the result of
calling the ``FSL_PARSEARGS`` attribute of the given tool, or ``None`` calling the ``FSL_PARSEARGS`` attribute of the given tool, or ``None``
if the tool does not have the function. if the tool does not have the function.
:arg tool: The ``FSLTool`` to be invoked. :arg tool: The ``FSLTool`` to be invoked.
:arg namespace: The ``argparse.Namespace`` object containing parsed
top-level arguments.
:arg argv: Command line arguments to be parsed. :arg argv: Command line arguments to be parsed.
""" """
......
...@@ -9,8 +9,7 @@ displays an about dialog for *FSLeyes*. ...@@ -9,8 +9,7 @@ displays an about dialog for *FSLeyes*.
""" """
import action import action
import fsl.fsleyes.about as aboutdlg
class AboutAction(action.Action): class AboutAction(action.Action):
...@@ -36,6 +35,8 @@ class AboutAction(action.Action): ...@@ -36,6 +35,8 @@ class AboutAction(action.Action):
def __showDialog(self): def __showDialog(self):
"""Creates and shows an :class:`.AboutDialog`. """ """Creates and shows an :class:`.AboutDialog`. """
import fsl.fsleyes.about as aboutdlg
dlg = aboutdlg.AboutDialog(self.__frame) dlg = aboutdlg.AboutDialog(self.__frame)
dlg.Show() dlg.Show()
dlg.CentreOnParent() dlg.CentreOnParent()
...@@ -25,11 +25,10 @@ import logging ...@@ -25,11 +25,10 @@ import logging
import textwrap import textwrap
import argparse import argparse
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs import fsl.fsleyes.perspectives as perspectives
import fsl.fsleyes.perspectives as perspectives import fsl.utils.status as status
import fsl.utils.status as status import fsl.utils.async as async
import fsl.utils.async as async import fsl.data.strings as strings
import fsl.data.strings as strings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -58,6 +57,8 @@ def parseArgs(argv): ...@@ -58,6 +57,8 @@ def parseArgs(argv):
:arg argv: command line arguments for ``fsleyes``. :arg argv: command line arguments for ``fsleyes``.
""" """
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
add_help=False, add_help=False,
formatter_class=argparse.RawDescriptionHelpFormatter) formatter_class=argparse.RawDescriptionHelpFormatter)
...@@ -111,9 +112,10 @@ def context(args, splash): ...@@ -111,9 +112,10 @@ def context(args, splash):
- the :class:`.FSLEyesSplash` frame - the :class:`.FSLEyesSplash` frame
""" """
import fsl.fsleyes.overlay as fsloverlay import fsl.fsleyes.overlay as fsloverlay
import fsl.fsleyes.displaycontext as displaycontext import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
import fsl.fsleyes.gl as fslgl import fsl.fsleyes.displaycontext as displaycontext
import fsl.fsleyes.gl as fslgl
import props import props
props.initGUI() props.initGUI()
...@@ -187,9 +189,10 @@ def interface(parent, args, ctx): ...@@ -187,9 +189,10 @@ def interface(parent, args, ctx):
:returns: the :class:`.FSLEyesFrame` that was created. :returns: the :class:`.FSLEyesFrame` that was created.
""" """
import wx import wx
import fsl.fsleyes.frame as fsleyesframe import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
import fsl.fsleyes.views as views import fsl.fsleyes.frame as fsleyesframe
import fsl.fsleyes.views as views
overlayList, displayCtx, splashFrame = ctx overlayList, displayCtx, splashFrame = ctx
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment