Source code for fsleyes_widgets.dialog

#!/usr/bin/env python
#
# dialog.py - Miscellaneous dialogs.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module contains a collection of basic dialog classes, available for
use throughout ``fslpy``. The available dialogs are:

.. autosummary::
   :nosignatures:

   SimpleMessageDialog
   TimeoutDialog
   ProcessingDialog
   TextEditDialog
   FSLDirDialog
"""


import            os
import os.path as op
import            threading

import            wx

import fsleyes_widgets as fw


[docs] class SimpleMessageDialog(wx.Dialog): """A simple, no-frills :class:`wx.Dialog` for displaying a message. The message can be updated via the :meth:`SetMessage` method. As a simple usage example:: import fsleyes_widgets.dialog as fsldlg dlg = fsldlg.SimpleMessageDialog(message='Loading data ...') dlg.Show() # load the data, like # you said you would # Data is loaded, so we # can kill the dialog dlg.Close() dlg.Destroy() The ``SimpleMessageDialog`` class supports the following styles: .. autosummary:: SMD_KEEP_CENTERED a ``SimpleMessageDialog`` looks something like this: .. image:: images/simplemessagedialog.png :scale: 50% :align: center """ def __init__(self, parent=None, message='', style=None): """Create a ``SimpleMessageDialog``. :arg parent: The :mod:`wx` parent object. :arg message: The initial message to show. :arg style: Only one style flag is supported, :data:`SMD_KEEP_CENTERED`. This flag is enabled by default. """ if style is None: style = SMD_KEEP_CENTERED if parent is None: parent = wx.GetApp().GetTopWindow() wx.Dialog.__init__(self, parent, style=wx.STAY_ON_TOP | wx.FULL_REPAINT_ON_RESIZE) self.__style = style self.__message = wx.StaticText( self, style=(wx.ST_ELLIPSIZE_MIDDLE | wx.ALIGN_CENTRE_HORIZONTAL | wx.ALIGN_CENTRE_VERTICAL)) self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.__sizer.Add(self.__message, border=25, proportion=1, flag=wx.CENTRE | wx.ALL) self.SetTransparent(240) self.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK)) self.SetSizer(self.__sizer) self.SetMessage(message)
[docs] def Show(self): """Overrides ``wx.Dialog.Show``. Calls that method, and calls ``wx.Yield``. """ wx.Dialog.Show(self) wx.Yield()
[docs] def SetMessage(self, msg): """Updates the message shown on this ``SimpleMessageDialog``. If the :data:`SMD_KEEP_CENTERED` style is set, the dialog is re-centered on its parent, to account for changes in the message width. """ msg = str(msg) self.__message.SetLabel(msg) # Figure out the dialog size # required to fit the message dc = wx.ClientDC(self.__message) width, height = dc.GetTextExtent(msg) # +50 to account for sizer borders (see __init__), # plus a bit more for good measure. In particular, # under GTK, the message seems to be vertically # truncated if we don't add some extra padding width += 60 height += 70 self.SetMinClientSize((width, height)) self.SetClientSize(( width, height)) self.Layout() self.__message.Layout() if self.__style & SMD_KEEP_CENTERED: self.CentreOnParent() # This ridiculousness seems to be # necessary to force a repaint on # all platforms (OSX, GTK, GTK/SSH) wx.Yield() self.Refresh() self.Update() self.__message.Refresh() self.__message.Update() wx.Yield()
# SimpleMessageDialog style flags SMD_KEEP_CENTERED = 1 """If set, the dialog will be re-centred on its parent whenever its message changes. """
[docs] class TimeoutDialog(SimpleMessageDialog): """A :class:`SimpleMessageDialog` which automatically destroys itself after a specified timeout period. .. note:: The timeout functionality will not work if you show the dialog by any means other than the :meth:`wx.Dialog.Show` or :meth:`wx.Dialog.ShowModal` methods ... but is there any other way of showing a :class:`wx.Dialog`? """ def __init__(self, parent, message, timeout=1000, **kwargs): """Create a ``TimeoutDialog``. :arg parent: The :mod:`wx` parent object. :arg message: The initial message to display. :arg timeout: Timeout period in milliseconds. :arg kwargs: Passed through to :meth:`SimpleMessageDialog.__init__`. """ SimpleMessageDialog.__init__(self, parent, message, **kwargs) self.__timeout = timeout def __close(self): """Closes and destroys this ``TimeoutDialog``. """ self.Close() self.Destroy()
[docs] def Show(self): """Shows this ``TimeoutDialog``, and sets up a callback to close it after the specified ``timeout``. """ wx.CallLater(self.__timeout, self.__close) SimpleMessageDialog.Show(self)
[docs] def ShowModal(self): """Shows this ``TimeoutDialog``, and sets up a callback to close it after the specified ``timeout``. """ wx.CallLater(self.__timeout, self.__close) SimpleMessageDialog.ShowModal(self)
[docs] class ProcessingDialog(SimpleMessageDialog): """A :class:`SimpleMessageDialog` which displays a message and runs a task in the background. User interaction is blocked while the task runs, and the dialog closes and destroys itself automatically on task completion. The task is simply passed in as a function. If the task supports it, the ``ProcessingDialog`` will pass it two message-updating functions, which can be used by the task to update the message being displayed. This functionality is controlled by the ``passFuncs``, ``messageFunc`` and ``errorFunc`` parameters to :meth:`__init__`. A ``ProcessingDialog`` must be displayed via the :meth:`Run` method, *not* with the :meth:`wx.Dialog.Show` or :meth:`wx.Dialog.ShowModal` methods. """ def __init__(self, parent, message, task, *args, **kwargs): """Create a ``ProcessingDialog``. :arg parent: The :mod:`wx` parent object. :arg message: Initial message to display. :arg task: The function to run. :arg args: Positional arguments passed to the ``task`` function. :arg kwargs: Keyword arguments passed to the ``task`` function. Some special keyword arguments are also accepted: =============== ================================================= Name Description =============== ================================================= ``passFuncs`` If ``True``, two extra keyword arguments are passed to the ``task`` function - ``messageFunc`` and ``errorFunc``. ``messageFunc`` is a function which accepts a single string as its argument; when it is called, the dialog message is updated to display the string. ``errorFunc`` is a function which accepts two arguemnts - a message string and an :exc:`Exception` instance. If the task detects an error, it may call this function. A new dialog is shown, containing the details of the error, to inform the user. ``messageFunc`` Overrides the default ``messageFunc`` described above. ``errorFunc`` Overrides the default ``errorFunc`` described above. =============== ================================================= """ passFuncs = kwargs.get('passFuncs', False) if not passFuncs: kwargs.pop('messageFunc', None) kwargs.pop('errorFunc', None) else: kwargs['messageFunc'] = kwargs.get('messageFunc', self.__defaultMessageFunc) kwargs['errortFunc'] = kwargs.get('errorFunc', self.__defaultErrorFunc) self.task = task self.args = args self.kwargs = kwargs self.message = message style = kwargs.pop('style', None) SimpleMessageDialog.__init__(self, parent, style=style)
[docs] def Run(self, mainThread=False): """Shows this ``ProcessingDialog``, and runs the ``task`` function passed to :meth:`__init__`. When the task completes, this dialog is closed and destroyed. :arg mainThread: If ``True`` the task is run in the current thread. Otherwise, the default behaviour is to run the task in a separate thread. :returns: the return value of the ``task`` function. .. note:: If ``mainThread=True``, the task should call :func:`wx.Yield` periodically - under GTK, there is a chance that this ``ProcessingDialog`` will not get drawn before the task begins. """ self.SetMessage(self.message) wx.Dialog.Show(self) self.SetFocus() self.Refresh() self.Update() wx.Yield() if mainThread: try: result = self.task(*self.args, **self.kwargs) except: self.Close() self.Destroy() raise else: returnVal = [None] def wrappedTask(): returnVal[0] = self.task(*self.args, **self.kwargs) thread = threading.Thread(target=wrappedTask) thread.start() while thread.isAlive(): thread.join(0.2) wx.Yield() result = returnVal[0] self.Close() self.Destroy() return result
[docs] def Show(self): """Raises a :exc:`NotImplementedError`.""" raise NotImplementedError('Use the Run method')
[docs] def ShowModal(self): """Raises a :exc:`NotImplementedError`.""" raise NotImplementedError('Use the Run method')
def __defaultMessageFunc(self, msg): """Default ``messageFunc``. Updates the message which is displayed on this ``ProcessingDialog``. See :meth:`SetMessage`. """ self.SetMessage(msg) def __defaultErrorFunc(self, msg, err): """Default ``errorFunc``. Opens a new dialog (a :class:`wx.MessageBox`) which contains a description of the error. """ err = str(err) msg = 'An error hass occurred: {}\n\nDetails: {}'.format(msg, err) title = 'Error' wx.MessageBox(msg, title, wx.ICON_ERROR | wx.OK)
[docs] class TextEditDialog(wx.Dialog): """A dialog which shows an editable/selectable text field. ``TextEditDialog`` supports the following styles: .. autosummary:: TED_READONLY TED_MULTILINE TED_OK TED_CANCEL TED_OK_CANCEL TED_COPY TED_COPY_MESSAGE A ``TextEditDialog`` looks something like this: .. image:: images/texteditdialog.png :scale: 50% :align: center """ def __init__(self, parent, title='', message='', text='', icon=None, style=None): """Create a ``TextEditDialog``. :arg parent: The :mod:`wx` parent object. :arg title: Dialog title. :arg message: Dialog message. :arg text: String to display in the text field. :arg icon: A :mod:`wx` icon identifier, such as :data:`wx.ICON_INFORMATION` or :data:`wx.ICON_WARNING`. :arg style: A combination of :data:`TED_READONLY`, :data:`TED_MULTILINE`, :data:`TED_OK`, :data:`TED_CANCEL`, :data:`TED_OK_CANCEL`, :data:`TED_COPY` and :data:`TED_COPY_MESSAGE` . Defaults to :data:`TED_OK`. """ if style is None: style = TED_OK wx.Dialog.__init__(self, parent, title=title, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) textStyle = 0 if style & TED_READONLY: textStyle |= wx.TE_READONLY if style & TED_MULTILINE: textStyle |= wx.TE_MULTILINE self.__message = wx.StaticText(self) self.__textEdit = wx.TextCtrl( self, style=textStyle) self.__message .SetLabel(message) self.__textEdit.SetValue(text) self.__showCopyMessage = style & TED_COPY_MESSAGE # set the min size of the text # ctrl so it can fit a few lines self.__textEdit.SetMinSize((-1, 120)) self.__textEdit.SetMaxSize((600, -1)) self.__ok = (-1, -1) self.__copy = (-1, -1) self.__cancel = (-1, -1) self.__icon = (-1, -1) self.__buttons = [] if icon is not None: icon = wx.ArtProvider.GetMessageBoxIcon(icon) if fw.wxFlavour() == fw.WX_PHOENIX: bmp = wx.Bitmap() else: bmp = wx.EmptyBitmap(icon.GetWidth(), icon.GetHeight()) bmp.CopyFromIcon(icon) self.__icon = wx.StaticBitmap(self) self.__icon.SetBitmap(bmp) if style & TED_OK: self.__ok = wx.Button(self, id=wx.ID_OK) self.__ok.Bind(wx.EVT_BUTTON, self.onOk) self.__buttons.append(self.__ok) if style & TED_CANCEL: self.__cancel = wx.Button(self, id=wx.ID_CANCEL) self.__cancel.Bind(wx.EVT_BUTTON, self.onCancel) self.__buttons.append(self.__cancel) if style & TED_COPY: self.__copy = wx.Button(self, label='Copy to clipboard') self.__copy.Bind(wx.EVT_BUTTON, self.__onCopy) self.__buttons.append(self.__copy) self.__textEdit.Bind(wx.EVT_CHAR_HOOK, self.__onCharHook) textSizer = wx.BoxSizer(wx.VERTICAL) iconSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer = wx.BoxSizer(wx.HORIZONTAL) mainSizer = wx.BoxSizer(wx.VERTICAL) textSizer.Add(self.__message, flag=wx.ALL | wx.CENTRE, border=20) textSizer.Add(self.__textEdit, flag=wx.ALL | wx.EXPAND, border=20, proportion=1) iconSizer.Add(self.__icon, flag=wx.ALL | wx.CENTRE, border=20) iconSizer.Add(textSizer, flag=wx.EXPAND, proportion=1) btnSizer.AddStretchSpacer() btnSizer.Add(self.__ok, flag=wx.ALL | wx.CENTRE, border=10) btnSizer.Add(self.__copy, flag=wx.ALL | wx.CENTRE, border=10) btnSizer.Add(self.__cancel, flag=wx.ALL | wx.CENTRE, border=10) btnSizer.Add((-1, 20)) mainSizer.Add(iconSizer, flag=wx.EXPAND, proportion=1) mainSizer.Add(btnSizer, flag=wx.EXPAND) self.SetSizer(mainSizer) self.Fit() def __onCharHook(self, ev): """Called on ``EVT_CHAR_HOOK`` events generated by the ``TextCtrl``. Implements tab-navigation, and makes the enter key behave as if the user had clicked the OK button. """ key = ev.GetKeyCode() if key not in (wx.WXK_TAB, wx.WXK_RETURN): ev.Skip() return # Dodgy, but I've had loads of trouble # under OSX - Navigate/HandleAsNavigationKey # do not work. if key == wx.WXK_TAB and len(self.__buttons) > 0: self.__buttons[0].SetFocus() elif key == wx.WXK_RETURN: self.onOk(None)
[docs] def onOk(self, ev): """Called when the *Ok* button is pressed. Ends the dialog. """ self.EndModal(wx.ID_OK)
[docs] def onCancel(self, ev): """Called when the *Cancel* button is pressed. Ends the dialog. """ self.EndModal(wx.ID_CANCEL)
def __onCopy(self, ev): """Called when the *Copy* button is pressed. Copies the text to the system clipboard, and pops up a :class:`TimeoutDialog` informing the user. """ text = self.__textEdit.GetValue() cb = wx.TheClipboard if cb.Open(): cb.SetData(wx.TextDataObject(text)) cb.Close() if self.__showCopyMessage: td = TimeoutDialog(self, 'Copied!', 1000) td.Show()
[docs] def SetMessage(self, message): """Set the message displayed on the dialog.""" self.__message.SetLabel(message)
[docs] def SetOkLabel(self, label): """Set the label to show on the *Ok* button.""" self.__ok.SetLabel(label)
[docs] def SetCopyLabel(self, label): """Sets the label to show on the *Copy* button.""" self.__copy.SetLabel(label)
[docs] def SetCancelLabel(self, label): """Sets the label to show on the *Cancel* button.""" self.__cancel.SetLabel(label)
[docs] def SetText(self, text): """Sets the text to show in the text field.""" self.__textEdit.SetValue(text)
[docs] def GetText(self): """Returns the text shown in the text field.""" return self.__textEdit.GetValue()
# TextEditDialog style flags TED_READONLY = 1 """If set, the user will not be able to change the text field contents.""" TED_MULTILINE = 2 """If set, the text field will span multiple lines. """ TED_OK = 4 """If set, an *Ok* button will be shown. """ TED_CANCEL = 8 """If set, a *Cancel* button will be shown. """ TED_OK_CANCEL = 12 """If set, *Ok* and *Cancel* buttons will be shown. Equivalent to ``TED_OK | TED_CANCEL``. """ TED_COPY = 16 """If set, a *Copy* button will be shown, allowing the use to copy the text to the system clipboard. """ TED_COPY_MESSAGE = 32 """If set, and if :attr:`TED_COPY` is also set, when the user chooses to copy the text to the system clipboard, a popup message is displayed. """
[docs] class FSLDirDialog(wx.Dialog): """A dialog which warns the user that the ``$FSLDIR`` environment variable is not set, and prompts them to identify the FSL installation directory. If the user selects a directory, the :meth:`getFSLDir` method can be called to retrieve their selection after the dialog has been closed. A ``FSLDirDialog`` looks something like this: .. image:: images/fsldirdialog.png :scale: 50% :align: center """ def __init__(self, parent, toolName, osxHint, defaultPath=None): """Create a ``FSLDirDialog``. :arg parent: The :mod:`wx` parent object. :arg toolName: The name of the tool which is running. :arg osxHint: If ``True``, an OSX-specific hint is added to the dialog. :arg defaultPath: Directory to initialise the selection dialog when prompting the user to select ``$FSLDIR``. Defaults to ``$HOME``. """ wx.Dialog.__init__(self, parent, title='$FSLDIR is not set') self.__fsldir = None self.__defaultPath = None self.__icon = wx.StaticBitmap(self) self.__message = wx.StaticText( self) self.__locate = wx.Button( self, id=wx.ID_OK) self.__skip = wx.Button( self, id=wx.ID_CANCEL) icon = wx.ArtProvider.GetMessageBoxIcon(wx.ICON_EXCLAMATION) if fw.wxFlavour() == fw.WX_PHOENIX: bmp = wx.Bitmap() else: bmp = wx.EmptyBitmap(icon.GetWidth(), icon.GetHeight()) bmp.CopyFromIcon(icon) self.__icon.SetBitmap(bmp) self.__message.SetLabel( 'The $FSLDIR environment variable is not set - {} ' 'may not behave correctly.'.format(toolName)) self.__locate .SetLabel('Locate $FSLDIR') self.__skip .SetLabel('Skip') self.__skip .Bind(wx.EVT_BUTTON, self.__onSkip) self.__locate.Bind(wx.EVT_BUTTON, self.__onLocate) self.__mainSizer = wx.BoxSizer(wx.HORIZONTAL) self.__contentSizer = wx.BoxSizer(wx.VERTICAL) self.__buttonSizer = wx.BoxSizer(wx.HORIZONTAL) self.__buttonSizer.Add((1, 1), flag=wx.EXPAND, proportion=1) self.__buttonSizer.Add(self.__locate) self.__buttonSizer.Add((20, 1)) self.__buttonSizer.Add(self.__skip) self.__contentSizer.Add(self.__message, flag=wx.EXPAND, proportion=1) self.__contentSizer.Add((1, 20)) self.__contentSizer.Add(self.__buttonSizer, flag=wx.EXPAND) # If running on OSX, add a message # telling the user about the # cmd+shift+g shortcut if osxHint: self.__hint = wx.StaticText( self, label='Hint: Press \u2318+\u21e7+G in the file ' 'dialog to manually type in a location.') self.__hint.SetForegroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) .ChangeLightness(75)) self.__contentSizer.Insert(2, self.__hint, flag=wx.EXPAND) self.__contentSizer.Insert(3, (1, 20)) else: self.__hint = None self.__mainSizer.Add(self.__icon, flag=wx.ALL | wx.CENTRE, border=20) self.__mainSizer.Add(self.__contentSizer, flag=wx.EXPAND | wx.ALL, proportion=1, border=20) self.__message.Wrap(self.GetSize().GetWidth()) self.SetSizer(self.__mainSizer) self.__mainSizer.Layout() self.__mainSizer.Fit(self) self.CentreOnParent()
[docs] def GetFSLDir(self): """If the user selected a directory, this method returns their selection. Otherwise, it returns ``None``. """ return self.__fsldir
def __onSkip(self, ev): """called when the *Skip* button is pushed. """ self.EndModal(wx.ID_CANCEL) def __onLocate(self, ev): """Called when the *Locate* button is pushed. Opens a :class:`wx.DirDialog` which allows the user to locate the FSL installation directory. """ if self.__defaultPath is not None: path = self.__defaultPath else: path = op.expanduser('~') dlg = wx.DirDialog( self, message='Select the directory in which FSL is installed', defaultPath=path, style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST) # If the user cancels the file # dialog, focus returns to the # original 'Choose dir' / 'Skip' # dialog. if dlg.ShowModal() != wx.ID_OK: return self.__fsldir = dlg.GetPath() self.EndModal(wx.ID_OK)
[docs] class CheckBoxMessageDialog(wx.Dialog): """A ``wx.Dialog`` which displays a message, one or more ``wx.CheckBox`` widgets, with associated messages, an *Ok* button, and (optionally) a *Cancel* button. """ def __init__(self, parent, title=None, message=None, cbMessages=None, cbStates=None, yesText=None, noText=None, cancelText=None, hintText=None, focus=None, icon=None, style=None): """Create a ``CheckBoxMessageDialog``. :arg parent: A ``wx`` parent object. :arg title: The dialog frame title. :arg message: Message to show on the dialog. :arg cbMessages: A list of labels, one for each ``wx.CheckBox``. :arg cbStates: A list of initial states (boolean values) for each ``wx.CheckBox``. :arg yesText: Text to show on the *yes*/confirm button. Defaults to *OK*. :arg noText: Text to show on the *no* button. If not provided, there will be no *no* button. :arg cancelText: Text to show on the *cancel* button. If not provided, there will be no cancel button. :arg hintText: If provided, shown as a "hint", in a slightly faded font, between the checkboxes and the buttons. :arg focus: One of ``'yes'``, ``'no'```, or ``'cancel'``, specifying which button should be given initial focus. :arg icon: A ``wx`` icon identifier (e.g. ``wx.ICON_EXCLAMATION``). :arg style: Passed through to the ``wx.Dialog.__init__`` method. Defaults to ``wx.DEFAULT_DIALOG_STYLE``. """ if style is None: style = wx.DEFAULT_DIALOG_STYLE if title is None: title = '' if message is None: message = '' if cbMessages is None: cbMessages = [''] if cbStates is None: cbStates = [False] * len(cbMessages) if yesText is None: yesText = 'OK' wx.Dialog.__init__(self, parent, title=title, style=style) if icon is not None: icon = wx.ArtProvider.GetMessageBoxIcon(icon) self.__icon = wx.StaticBitmap(self) if fw.wxFlavour() == fw.WX_PHOENIX: bmp = wx.Bitmap() else: bmp = wx.EmptyBitmap(icon.GetWidth(), icon.GetHeight()) bmp.CopyFromIcon(icon) self.__icon.SetBitmap(bmp) else: self.__icon = (1, 1) self.__checkboxes = [] for msg, state in zip(cbMessages, cbStates): cb = wx.CheckBox(self, label=msg) cb.SetValue(state) self.__checkboxes.append(cb) self.__message = wx.StaticText(self, label=message) self.__yesButton = wx.Button( self, label=yesText, id=wx.ID_YES) self.__yesButton.Bind(wx.EVT_BUTTON, self.__onYesButton) if noText is not None: self.__noButton = wx.Button(self, label=noText, id=wx.ID_NO) self.__noButton.Bind(wx.EVT_BUTTON, self.__onNoButton) else: self.__noButton = None if cancelText is not None: self.__cancelButton = wx.Button(self, label=cancelText, id=wx.ID_CANCEL) self.__cancelButton.Bind(wx.EVT_BUTTON, self.__onCancelButton) else: self.__cancelButton = None if hintText is not None: self.__hint = wx.StaticText(self, label=hintText) self.__hint.SetForegroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) .ChangeLightness(75)) else: self.__hint = None self.__mainSizer = wx.BoxSizer(wx.HORIZONTAL) self.__contentSizer = wx.BoxSizer(wx.VERTICAL) self.__btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.__contentSizer.Add(self.__message, flag=wx.EXPAND, proportion=1) self.__contentSizer.Add((1, 20), flag=wx.EXPAND) for cb in self.__checkboxes: self.__contentSizer.Add(cb, flag=wx.EXPAND) if self.__hint is not None: self.__contentSizer.Add((1, 20), flag=wx.EXPAND) self.__contentSizer.Add(self.__hint, flag=wx.EXPAND) self.__contentSizer.Add((1, 20), flag=wx.EXPAND) self.__btnSizer.Add((1, 1), flag=wx.EXPAND, proportion=1) buttons = [self.__yesButton, self.__noButton, self.__cancelButton] buttons = [b for b in buttons if b is not None] for i, b in enumerate(buttons): self.__btnSizer.Add(b) if i != len(buttons) - 1: self.__btnSizer.Add((5, 1), flag=wx.EXPAND) self.__contentSizer.Add(self.__btnSizer, flag=wx.EXPAND) self.__mainSizer.Add(self.__icon, flag=wx.ALL | wx.CENTRE, border=20) self.__mainSizer.Add(self.__contentSizer, flag=wx.EXPAND | wx.ALL, proportion=1, border=20) self.__message.Wrap(self.GetSize().GetWidth()) yes = self.__yesButton no = self.__noButton cncl = self.__cancelButton if focus == 'yes': yes .SetDefault() elif focus == 'no' and no is not None: no .SetDefault() elif focus == 'cancel' and cncl is not None: cncl.SetDefault() self.SetSizer(self.__mainSizer) self.Layout() self.Fit() self.CentreOnParent()
[docs] def CheckBoxState(self, index=0): """After this ``CheckBoxMessageDialog`` has been closed, this method will retrieve the state of the dialog ``CheckBox``. """ return self.__checkboxes[index].GetValue()
def __onYesButton(self, ev): """Called when the button on this ``CheckBoxMessageDialog`` is clicked. Closes the dialog. """ self.EndModal(wx.ID_YES) def __onNoButton(self, ev): """Called when the button on this ``CheckBoxMessageDialog`` is clicked. Closes the dialog. """ self.EndModal(wx.ID_NO) def __onCancelButton(self, ev): """If the ``CHECKBOX_MSGDLG_CANCEL_BUTTON`` style was set, this method is called when the cancel button is clicked. Closes the dialog. """ self.EndModal(wx.ID_CANCEL)