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):
: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:
args = sys.argv[1:]
......@@ -94,88 +90,118 @@ def main(args=None):
allTools = _getFSLToolNames()
fslTool, namespace, toolArgv = _parseTopLevelArgs(args, allTools)
# If this is a GUI tool, create
# the wx application before calling
# fslTool.init(), in case it does
# any GUI stuff.
if fslTool.interface is not None:
import wx
app = wx.App()
# GUI or command-line tool?
if fslTool.interface is not None: _runGUITool(fslTool, toolArgv)
else: _runCLITool(fslTool, toolArgv)
def _runGUITool(fslTool, toolArgv):
"""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
# function if there is one
if fslTool.init is not None: initVal = fslTool.init()
else: initVal = None
# Parse the tool-specific
# command line arguments
toolNamespace = _parseToolArgs(fslTool, namespace, toolArgv)
# We are going do all processing on the
# wx.MainLoop, so the GUI can be shown
# 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?
if fslTool.interface is not None:
# Parse the tool-specific
# 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
# wx.MainLoop, 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():
if fslTool.context is not None:
ctx = fslTool.context(toolNamespace, initVal)
else:
ctx = None
frame = _buildGUI(toolNamespace, fslTool, ctx, fslEnvActive)
frame.Show()
# See comment below
dummyFrame.Destroy()
_fslDirWarning(frame, fslTool.toolName, fslEnvActive)
if namespace.wxinspect:
import wx.lib.inspection
wx.lib.inspection.InspectionTool().Show()
time.sleep(0.1)
wx.CallAfter(realBuild)
# Create the wx.App object, and create a dummy
# frame. If we don't create a dummy frame, the
# wx.MainLoop call will just return immediately.
# The buildGUI function above will kill the dummy
# frame when it has created the real interface.
dummyFrame = wx.Frame(None)
threading.Thread(target=buildGUI).start()
# The wx.App was created above,
# before calling fslTool.init()
app.MainLoop()
# Or is this a CLI tool?
elif fslTool.execute is not None:
if fslTool.context is not None:
ctx = fslTool.context(toolNamespace, initVal)
else:
ctx = None
# Build the GUI
frame = _buildGUI(toolNamespace, fslTool, ctx, fslEnvActive)
frame.Show()
# See comment about the
# dummy frame below
dummyFrame.Destroy()
_fslDirWarning(frame, fslTool.toolName, fslEnvActive)
time.sleep(0.1)
wx.CallAfter(realBuild)
# Create the wx.App object, and create a dummy
# frame. If we don't create a dummy frame, the
# wx.MainLoop call will just return immediately.
# The buildGUI function above will kill the dummy
# frame when it has created the real interface.
dummyFrame = wx.Frame(None)
threading.Thread(target=buildGUI).start()
# The wx.App was created above,
# before calling fslTool.init()
app.MainLoop()
def _runCLITool(fslTool, toolArgv):
"""Runs the given ``FSLTool``, which is assumed to be a command-line (i.e.
non-GUI) tool.
:arg fslTool: The ``FSLTool`` to run - see the :func:`_loadFSLTool`
function.
:arg toolArgv: Unparsed tool-specific command line arguments.
"""
if fslTool.execute is None:
return
# Call the tool's init
# function if there is one
if fslTool.init is not None: initVal = fslTool.init()
else: initVal = None
# Parse the tool-specific
# command line arguments
namespace = _parseToolArgs(fslTool, toolArgv)
initVal = None
ctx = None
if fslTool.init is not None: initVal = fslTool.init()
if fslTool.context is not None: ctx = fslTool.context(namespace,
initVal)
_fslDirWarning(None, fslTool.toolName, fslEnvActive)
fslTool.execute(toolNamespace, ctx)
_fslDirWarning(None, fslTool.toolName, 'FSLDIR' in os.environ)
fslTool.execute(namespace, ctx)
def runTool(toolName, args, **kwargs):
......@@ -343,10 +369,6 @@ def _parseTopLevelArgs(argv, allTools):
'-m', '--memory', action='store_true',
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='?')
# No arguments at all?
......@@ -481,16 +503,12 @@ def _parseTopLevelArgs(argv, allTools):
return fslTool, namespace, toolArgv
def _parseToolArgs(tool, namespace, argv):
def _parseToolArgs(tool, argv):
"""Parses tool-specific command-line arguments. Returns the result of
calling the ``FSL_PARSEARGS`` attribute of the given tool, or ``None``
if the tool does not have the function.
: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.
"""
......
......@@ -9,8 +9,7 @@ displays an about dialog for *FSLeyes*.
"""
import action
import fsl.fsleyes.about as aboutdlg
import action
class AboutAction(action.Action):
......@@ -36,6 +35,8 @@ class AboutAction(action.Action):
def __showDialog(self):
"""Creates and shows an :class:`.AboutDialog`. """
import fsl.fsleyes.about as aboutdlg
dlg = aboutdlg.AboutDialog(self.__frame)
dlg.Show()
dlg.CentreOnParent()
......@@ -25,11 +25,10 @@ import logging
import textwrap
import argparse
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
import fsl.fsleyes.perspectives as perspectives
import fsl.utils.status as status
import fsl.utils.async as async
import fsl.data.strings as strings
import fsl.fsleyes.perspectives as perspectives
import fsl.utils.status as status
import fsl.utils.async as async
import fsl.data.strings as strings
log = logging.getLogger(__name__)
......@@ -58,6 +57,8 @@ def parseArgs(argv):
:arg argv: command line arguments for ``fsleyes``.
"""
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.RawDescriptionHelpFormatter)
......@@ -111,9 +112,10 @@ def context(args, splash):
- the :class:`.FSLEyesSplash` frame
"""
import fsl.fsleyes.overlay as fsloverlay
import fsl.fsleyes.displaycontext as displaycontext
import fsl.fsleyes.gl as fslgl
import fsl.fsleyes.overlay as fsloverlay
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
import fsl.fsleyes.displaycontext as displaycontext
import fsl.fsleyes.gl as fslgl
import props
props.initGUI()
......@@ -187,9 +189,10 @@ def interface(parent, args, ctx):
:returns: the :class:`.FSLEyesFrame` that was created.
"""
import wx
import fsl.fsleyes.frame as fsleyesframe
import fsl.fsleyes.views as views
import wx
import fsl.fsleyes.fsleyes_parseargs as fsleyes_parseargs
import fsl.fsleyes.frame as fsleyesframe
import fsl.fsleyes.views as views
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