Browse Source

filling out model

pull/150/head
chriskiehl 9 years ago
parent
commit
b5a1303222
9 changed files with 321 additions and 139 deletions
  1. 37
      gooey/gui/controller.py
  2. 165
      gooey/gui/model.py
  3. 105
      gooey/gui/presenter.py
  4. 12
      gooey/gui/widgets/choosers.py
  5. 25
      gooey/gui/widgets/components.py
  6. 96
      gooey/gui/widgets/widget_pack.py
  7. 16
      gooey/gui/windows/advanced_config.py
  8. 3
      gooey/gui/windows/base_window.py
  9. 1
      gooey/python_bindings/config_generator.py

37
gooey/gui/controller.py

@ -9,6 +9,7 @@ from multiprocessing.dummy import Pool
from gooey.gui.lang import i18n from gooey.gui.lang import i18n
from gooey.gui import events from gooey.gui import events
from gooey.gui.model import MyModel
from gooey.gui.presenter import Presenter from gooey.gui.presenter import Presenter
from gooey.gui.pubsub import pub from gooey.gui.pubsub import pub
from gooey.gui.util.taskkill import taskkill from gooey.gui.util.taskkill import taskkill
@ -26,7 +27,7 @@ class Controller(object):
# todo: model! # todo: model!
self.build_spec = build_spec self.build_spec = build_spec
self.view = BaseWindow(build_spec, layout_type=self.build_spec['layout_type']) self.view = BaseWindow(build_spec, layout_type=self.build_spec['layout_type'])
self.presentation = Presenter(self.view, self.build_spec)
self.presentation = Presenter(self.view, MyModel(self.build_spec))
self.presentation.initialize_view() self.presentation.initialize_view()
self._process = None self._process = None
@ -34,7 +35,7 @@ class Controller(object):
# wire up all the observers # wire up all the observers
pub.subscribe(self.on_cancel, events.WINDOW_CANCEL) pub.subscribe(self.on_cancel, events.WINDOW_CANCEL)
pub.subscribe(self.on_stop, events.WINDOW_STOP) pub.subscribe(self.on_stop, events.WINDOW_STOP)
pub.subscribe(self.on_start, events.WINDOW_START)
# pub.subscribe(self.on_start, events.WINDOW_START)
pub.subscribe(self.on_restart, events.WINDOW_RESTART) pub.subscribe(self.on_restart, events.WINDOW_RESTART)
pub.subscribe(self.on_close, events.WINDOW_CLOSE) pub.subscribe(self.on_close, events.WINDOW_CLOSE)
pub.subscribe(self.on_edit, events.WINDOW_EDIT) pub.subscribe(self.on_edit, events.WINDOW_EDIT)
@ -61,13 +62,15 @@ class Controller(object):
sys.exit() sys.exit()
def on_start(self): def on_start(self):
if not self.skipping_config() and not self.required_section_complete():
return self.view.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
cmd_line_args = self.view.GetOptions()
command = '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_line_args)
pub.send_message(events.WINDOW_CHANGE, view_name=views.RUNNING_SCREEN)
self.run_client_code(command)
print self.presentation.view.required_section.get_values()
print self.presentation.view.optional_section.get_values()
# if not self.skipping_config() and not self.required_section_complete():
# return self.view.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
#
# cmd_line_args = self.view.GetOptions()
# command = '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_line_args)
# pub.send_message(events.WINDOW_CHANGE, view_name=views.RUNNING_SCREEN)
# self.run_client_code(command)
def on_stop(self): def on_stop(self):
self.ask_stop() self.ask_stop()
@ -154,14 +157,14 @@ class Controller(object):
pub.send_message(events.WINDOW_CHANGE, view_name=views.ERROR_SCREEN) pub.send_message(events.WINDOW_CHANGE, view_name=views.ERROR_SCREEN)
self.error_dialog() self.error_dialog()
def skipping_config(self):
return self.build_spec['manual_start']
def required_section_complete(self):
required_section = self.view.GetRequiredArgs()
if len(required_section) == 0:
return True # no requirements!
return not any(req == '' for req in required_section)
# def skipping_config(self):
# return self.build_spec['manual_start']
#
# def required_section_complete(self):
# required_section = self.view.GetRequiredArgs()
# if len(required_section) == 0:
# return True # no requirements!
# return not any(req == '' for req in required_section)
def success_dialog(self): def success_dialog(self):
self.view.show_dialog(i18n._("execution_finished"), i18n._('success_message'), wx.ICON_INFORMATION) self.view.show_dialog(i18n._("execution_finished"), i18n._('success_message'), wx.ICON_INFORMATION)

165
gooey/gui/model.py

@ -0,0 +1,165 @@
import os
from collections import namedtuple
from itertools import chain
from gooey.gui.lang.i18n import _
# MyWidget = namedtuple('MyWidget', 'type title help nargs commands choices')
from gooey.gui.util.quoting import quote
class MyWidget(object):
def __init__(self, type, title, help, default, nargs, commands, choices):
self.type = type
self.title = title
self.help = help
self.default = default
self._value = default
self.nargs = nargs
self.commands = commands
self.choices = choices
@property
def value(self):
# TODO: split into stategy or subclass thingie
if self.type == 'CheckBox':
return self.commands[0] if self._value else None
if self.type == 'RadioGroup':
try:
return self.commands[self._value.index(True)][0]
except ValueError:
return None
if self.type == 'MultiFileChooser':
value = ' '.join(quote(x) for x in self._value.split(os.pathsep) if x)
if self.commands and value:
return '{} {}'.format(self.commands[0], value)
return value or None
# if self.type == 'TextField':
# if self.commands and self._value:
# return '{} {}'.format(self.commands[0], quote(self._value))
# else:
# return quote(self._value) if self._value else ''
if self.type == 'CommandField':
if self.commands and self._value:
return '{} {}'.format(self.commands[0], self._value)
else:
return self._value or None
if self.type == 'Counter':
'''
Returns
str(option_string * DropDown Value)
e.g.
-vvvvv
'''
if not str(self._value).isdigit():
return None
arg = str(self.commands[0]).replace('-', '')
repeated_args = arg * int(self._value)
return '-' + repeated_args
if self.type == 'Dropdown':
if self._value == self.default:
return ''
elif self.commands and self._value:
return '{} {}'.format(self.commands[0], quote(self._value))
else:
return quote(self._value) if self._value else ''
else:
if self.commands and self._value:
return '{0} {1}'.format(self.commands[0], quote(self._value))
else:
return quote(self._value) if self._value else None
@value.setter
def value(self, val):
self._value = val
class MyModel(object):
'''
Needs to:
- sort the args based on a strategy
-
'''
def __init__(self, build_spec):
self.build_spec = build_spec
self.program_name = self.build_spec['program_name']
self.default_size = self.build_spec['default_size']
self.heading_title = _("settings_title")
self.heading_subtitle = self.build_spec['program_description'] or ''
self.use_monospace_font = self.build_spec.get('monospace_display')
self.stop_button_disabled = self.build_spec['disable_stop_button']
reqs, opts = self.group_arguments(self.build_spec['widgets'])
self.required_args = reqs
self.optional_args = opts
def is_valid(self):
# TODO: fix skipping_config.. whatever that did
# currently breaks when you supply it as a decorator option
# return self.skipping_config() and self.required_section_complete()
return self.is_required_section_complete()
def skipping_config(self):
return self.build_spec['manual_start']
def is_required_section_complete(self):
completed_values = filter(None, [arg.value for arg in self.required_args])
return len(self.required_args) == len(completed_values)
def build_command_line_string(self):
"""
returns the collective values from all of the
widgets contained in the panel"""
# _f = lambda lst: [x for x in lst if x is not None]
optional_args = [arg.value for arg in self.optional_args]
required_args = [c.value for c in self.required_args if c.commands]
position_args = [c.value for c in self.required_args if not c.commands]
if position_args:
position_args.insert(0, "--")
return ' '.join(filter(None, chain(required_args, optional_args, position_args)))
def group_arguments(self, widget_list):
is_required = lambda widget: widget['required']
not_checkbox = lambda widget: widget['type'] != 'CheckBox'
required_args, optional_args = self.partition(widget_list, is_required)
if self.build_spec['group_by_type']:
optional_args = chain(*self.partition(optional_args, not_checkbox))
return map(self.to_object, required_args), map(self.to_object, optional_args)
@staticmethod
def partition(collection, condition):
return filter(condition, collection), filter(lambda x: not condition(x), collection)
def to_object(self, data):
details = data['data']
return MyWidget(
data['type'],
self.maybe_unpack(details, 'display_name'),
self.maybe_unpack(details, 'help'),
self.maybe_unpack(details, 'default'),
self.maybe_unpack(details, 'nargs'),
self.maybe_unpack(details, 'commands'),
self.maybe_unpack(details, 'choices')
)
@staticmethod
def maybe_unpack(collection, attr):
# TODO: RadioGroups need to support defaults
try:
if isinstance(collection, list):
return [item[attr] for item in collection]
return collection[attr]
except:
return None

105
gooey/gui/presenter.py

@ -2,41 +2,24 @@ from collections import namedtuple
from gooey.gui import component_builder from gooey.gui import component_builder
from gooey.gui.lang.i18n import _ from gooey.gui.lang.i18n import _
is_required = lambda widget: widget['required']
SimpleArg = namedtuple('SimpleArg', 'title msg type')
from gooey.gui.pubsub import pub
from gooey.gui import events
class Presenter(object): class Presenter(object):
def __init__(self, view, build_spec):
def __init__(self, view, model):
self.view = view self.view = view
self.build_spec = build_spec
def initialize_view(self):
self.view.window_title = self.build_spec['program_name']
self.view.window_size = self.build_spec['default_size']
# widgets = component_builder.build_components(self.build_spec['widgets'])
required_args, optional_args = self.partition(self.build_spec['widgets'], is_required)
self.view.required_section.populate([SimpleArg(x['data']['display_name'], x['data']['help'], x['type']) for x in required_args])
self.model = model
optionals = []
for x in optional_args:
if x['type'] != 'RadioGroup':
optionals.append(SimpleArg(x['data']['display_name'], x['data']['help'], x['type']))
else:
names = [y['display_name'] for y in x['data']]
msgs = [y['help'] for y in x['data']]
optionals.append(SimpleArg(names, msgs, x['type']))
pub.subscribe(self.on_start, events.WINDOW_START)
self.view.optional_section.populate(optionals)
def initialize_view(self):
self.view.window_title = self.model.program_name
self.view.window_size = self.model.default_size
# self.view.optional_section.populate(widgets.optional_args)
self.view.required_section.populate(self.model.required_args)
self.view.optional_section.populate(self.model.optional_args)
if self.build_spec.get('monospace_display'):
if self.model.use_monospace_font:
self.view.set_display_font_style('monospace') self.view.set_display_font_style('monospace')
if self.should_disable_stop_button(): if self.should_disable_stop_button():
@ -46,54 +29,38 @@ class Presenter(object):
self.syncronize_from_model() self.syncronize_from_model()
def on_start(self):
self.update_model()
if not self.model.is_valid():
self.view.show_missing_args_dialog()
cmd_line_args = self.model.build_command_line_string()
print cmd_line_args
# cmd_line_args = self.view.GetOptions()
# command = '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_line_args)
# pub.send_message(events.WINDOW_CHANGE, view_name=views.RUNNING_SCREEN)
# self.run_client_code(command)
def update_model(self):
self.update_list(self.model.required_args, self.view.required_section.get_values())
self.update_list(self.model.optional_args, self.view.optional_section.get_values())
def update_list(self, collection, new_values):
for index, val in enumerate(new_values):
collection[index].value = val
@staticmethod @staticmethod
def partition(collection, condition): def partition(collection, condition):
return filter(condition, collection), filter(lambda x: not condition(x), collection) return filter(condition, collection), filter(lambda x: not condition(x), collection)
def syncronize_from_model(self): def syncronize_from_model(self):
self.view.heading_title = _("settings_title")
self.view.heading_subtitle = self.build_spec['program_description'] or ''
#
# def _init_pages(self):
# def config():
# self.view.heading_title = 'asdf'
# self.view.heading_subtitle = 'asdf'
# self.view.show('settings_img')
# self.view.hide('check_mark', 'running_img', 'error_symbol')
#
# def running():
# self.view._header.SetLabel(_("running_title"))
# self.view._subheader.SetLabel(_('running_msg'))
# self.view._check_mark.Hide()
# self.view._settings_img.Hide()
# self.view._running_img.Show()
# self.view._error_symbol.Hide()
# self.view.Layout()
#
# def success():
# self.view._header.SetLabel(_('finished_title'))
# self.view._subheader.SetLabel(_('finished_msg'))
# self.view._running_img.Hide()
# self.view._check_mark.Show()
# self.view.Layout()
#
# def error():
# self.view._header.SetLabel(_('finished_title'))
# self.view._subheader.SetLabel(_('finished_error'))
# self.view._running_img.Hide()
# self.view._error_symbol.Show()
# self.view.Layout()
#
# self.layouts = locals()
def is_column_layout(self):
return self.build_spec['layout_type'] == 'column'
self.view.heading_title = self.model.heading_title
self.view.heading_subtitle = self.model.heading_subtitle
def should_disable_stop_button(self): def should_disable_stop_button(self):
return self.build_spec['disable_stop_button']
return self.model.stop_button_disabled

12
gooey/gui/widgets/choosers.py

@ -17,7 +17,7 @@
# # Widgets # # Widgets
# self.title = None # self.title = None
# self.help_msg = None # self.help_msg = None
# self.text_box = None
# self.widget = None
# self.button = None # self.button = None
# self.panel = None # self.panel = None
# #
@ -29,7 +29,7 @@
# self.panel.SetDoubleBuffered(True) # self.panel.SetDoubleBuffered(True)
# self.title = self.CreateNameLabelWidget(self.panel) # self.title = self.CreateNameLabelWidget(self.panel)
# self.help_msg = self.CreateHelpMsgWidget(self.panel) # self.help_msg = self.CreateHelpMsgWidget(self.panel)
# self.text_box = wx.TextCtrl(self.panel)
# self.widget = wx.TextCtrl(self.panel)
# self.button = wx.Button(self.panel, label=self.button_text, size=(73, 23)) # self.button = wx.Button(self.panel, label=self.button_text, size=(73, 23))
# #
# vertical_container = wx.BoxSizer(wx.VERTICAL) # vertical_container = wx.BoxSizer(wx.VERTICAL)
@ -44,7 +44,7 @@
# else: # else:
# vertical_container.AddStretchSpacer(1) # vertical_container.AddStretchSpacer(1)
# #
# widget_sizer.Add(self.text_box, 1, wx.EXPAND)
# widget_sizer.Add(self.widget, 1, wx.EXPAND)
# widget_sizer.AddSpacer(10) # widget_sizer.AddSpacer(10)
# widget_sizer.Add(self.button, 0) # widget_sizer.Add(self.button, 0)
# #
@ -95,7 +95,7 @@
# if dlg.ShowModal() == wx.ID_OK # if dlg.ShowModal() == wx.ID_OK
# else None) # else None)
# if result: # if result:
# self.text_box.SetLabelText(result)
# self.widget.SetLabelText(result)
# #
# #
# class DirectoryChooser(AbstractChooser): # class DirectoryChooser(AbstractChooser):
@ -108,7 +108,7 @@
# if dlg.ShowModal() == wx.ID_OK # if dlg.ShowModal() == wx.ID_OK
# else None) # else None)
# if result: # if result:
# self.text_box.SetLabelText(result)
# self.widget.SetLabelText(result)
# #
# #
# class CalendarChooser(AbstractChooser): # class CalendarChooser(AbstractChooser):
@ -120,7 +120,7 @@
# dlg = CalendarDlg(self.panel) # dlg = CalendarDlg(self.panel)
# dlg.ShowModal() # dlg.ShowModal()
# if dlg.GetPath(): # if dlg.GetPath():
# self.text_box.SetLabelText(dlg.GetPath())
# self.widget.SetLabelText(dlg.GetPath())
# #
# #
# #

25
gooey/gui/widgets/components.py

@ -52,6 +52,9 @@ class BaseGuiComponent(object):
return self.panel return self.panel
def bind(self, *args, **kwargs):
print self.widget_pack.widget.Bind(*args, **kwargs)
def get_title(self): def get_title(self):
return self.title.GetLabel() return self.title.GetLabel()
@ -95,8 +98,8 @@ class BaseGuiComponent(object):
self.help_msg.Wrap(container_width) self.help_msg.Wrap(container_width)
evt.Skip() evt.Skip()
def GetValue(self):
return self.widget_pack.getValue()
def get_value(self):
return self.widget_pack.get_value()
# def HasOptionString(self): # def HasOptionString(self):
# return bool(self.widget_pack.option_string) # return bool(self.widget_pack.option_string)
@ -148,6 +151,8 @@ class CheckBox(BaseGuiComponent):
msg.Wrap(container_width) msg.Wrap(container_width)
evt.Skip() evt.Skip()
def get_value(self):
return self.widget.GetValue()
# def GetValue(self): # def GetValue(self):
# return self.option_strings if self.widget.GetValue() else '' # return self.option_strings if self.widget.GetValue() else ''
# #
@ -215,12 +220,15 @@ class RadioGroup(object):
msg.Wrap(container_width) msg.Wrap(container_width)
evt.Skip() evt.Skip()
def GetValue(self):
vals = [button.GetValue() for button in self.radio_buttons]
try:
return self.option_strings[vals.index(True)][0]
except:
return ''
def get_value(self):
return [button.GetValue() for button in self.radio_buttons]
# def GetValue(self):
# vals = [button.GetValue() for button in self.radio_buttons]
# try:
# return self.option_strings[vals.index(True)][0]
# except:
# return ''
def HasOptionString(self): def HasOptionString(self):
return bool(self.option_strings) return bool(self.option_strings)
@ -230,6 +238,7 @@ class RadioGroup(object):
def build_subclass(name, widget_class): def build_subclass(name, widget_class):
# this seemed faster than typing class X a bunch
return type(name, (BaseGuiComponent,), {'widget_class': widget_class}) return type(name, (BaseGuiComponent,), {'widget_class': widget_class})

96
gooey/gui/widgets/widget_pack.py

@ -45,29 +45,32 @@ class BaseChooser(WidgetPack):
self.button_text = i18n._('browse') self.button_text = i18n._('browse')
self.option_string = None self.option_string = None
self.parent = None self.parent = None
self.text_box = None
self.widget = None
self.button = None self.button = None
def build(self, parent, data): def build(self, parent, data):
self.parent = parent self.parent = parent
self.option_string = self.get_command(data) self.option_string = self.get_command(data)
self.text_box = wx.TextCtrl(self.parent)
self.text_box.AppendText(safe_default(data, ''))
self.text_box.SetMinSize((0, -1))
dt = FileDrop(self.text_box)
self.text_box.SetDropTarget(dt)
self.widget = wx.TextCtrl(self.parent)
self.widget.AppendText(safe_default(data, ''))
self.widget.SetMinSize((0, -1))
dt = FileDrop(self.widget)
self.widget.SetDropTarget(dt)
self.button = wx.Button(self.parent, label=self.button_text, size=(73, 23)) self.button = wx.Button(self.parent, label=self.button_text, size=(73, 23))
widget_sizer = wx.BoxSizer(wx.HORIZONTAL) widget_sizer = wx.BoxSizer(wx.HORIZONTAL)
widget_sizer.Add(self.text_box, 1, wx.EXPAND)
widget_sizer.Add(self.widget, 1, wx.EXPAND)
widget_sizer.AddSpacer(10) widget_sizer.AddSpacer(10)
widget_sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) widget_sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
parent.Bind(wx.EVT_BUTTON, self.onButton, self.button) parent.Bind(wx.EVT_BUTTON, self.onButton, self.button)
return widget_sizer return widget_sizer
def get_value(self):
return self.widget.GetValue()
# def getValue(self): # def getValue(self):
# value = self.text_box.GetValue()
# value = self.widget.GetValue()
# if self.option_string and value: # if self.option_string and value:
# return '{0} {1}'.format(self.option_string, quote(value)) # return '{0} {1}'.format(self.option_string, quote(value))
# else: # else:
@ -91,7 +94,7 @@ class BaseFileChooser(BaseChooser):
if dlg.ShowModal() == wx.ID_OK if dlg.ShowModal() == wx.ID_OK
else None) else None)
if result: if result:
self.text_box.SetValue(result)
self.widget.SetValue(result)
def get_path(self, dlg): def get_path(self, dlg):
return dlg.GetPath() return dlg.GetPath()
@ -103,7 +106,7 @@ class BaseMultiFileChooser(BaseFileChooser):
self.dialog = dialog self.dialog = dialog
# def getValue(self): # def getValue(self):
# value = ' '.join(quote(x) for x in self.text_box.GetValue().split(os.pathsep) if x)
# value = ' '.join(quote(x) for x in self.widget.GetValue().split(os.pathsep) if x)
# if self.option_string and value: # if self.option_string and value:
# return '{} {}'.format(self.option_string, value) # return '{} {}'.format(self.option_string, value)
# return value or '' # return value or ''
@ -151,6 +154,9 @@ class TextInputPayload(WidgetPack):
self.widget.AppendText(safe_default(data, '')) self.widget.AppendText(safe_default(data, ''))
return self.widget return self.widget
def get_value(self):
return self.widget.GetValue()
# def getValue(self): # def getValue(self):
# if self.no_quoting: # if self.no_quoting:
# _quote = lambda value: value # _quote = lambda value: value
@ -188,18 +194,21 @@ class DropdownPayload(WidgetPack):
) )
return self.widget return self.widget
def getValue(self):
if self.no_quoting:
_quote = lambda value: value
else:
_quote = quote
value = self.widget.GetValue()
if value == self.default_value:
return ''
elif value and self.option_string:
return '{} {}'.format(self.option_string, _quote(value))
else:
return _quote(value) if value else ''
def get_value(self):
return self.widget.GetValue()
# def getValue(self):
# if self.no_quoting:
# _quote = lambda value: value
# else:
# _quote = quote
# value = self.widget.GetValue()
# if value == self.default_value:
# return ''
# elif value and self.option_string:
# return '{} {}'.format(self.option_string, _quote(value))
# else:
# return _quote(value) if value else ''
def _SetValue(self, text): def _SetValue(self, text):
# used for testing # used for testing
@ -222,19 +231,36 @@ class CounterPayload(WidgetPack):
) )
return self.widget return self.widget
def getValue(self):
'''
Returns
str(option_string * DropDown Value)
e.g.
-vvvvv
'''
dropdown_value = self.widget.GetValue()
if not str(dropdown_value).isdigit():
return ''
arg = str(self.option_string).replace('-', '')
repeated_args = arg * int(dropdown_value)
return '-' + repeated_args
def get_value(self):
return self.widget.GetValue()
# def getValue(self):
# '''
# Returns
# str(option_string * DropDown Value)
# e.g.
# -vvvvv
# '''
# return self.widget.GetValue()
# if not str(dropdown_value).isdigit():
# return ''
# arg = str(self.option_string).replace('-', '')
# repeated_args = arg * int(dropdown_value)
# return '-' + repeated_args
# def getValue(self):
# '''
# Returns
# str(option_string * DropDown Value)
# e.g.
# -vvvvv
# '''
# dropdown_value = self.widget.GetValue()
# if not str(dropdown_value).isdigit():
# return ''
# arg = str(self.option_string).replace('-', '')
# repeated_args = arg * int(dropdown_value)
# return '-' + repeated_args
class DirDialog(wx.DirDialog): class DirDialog(wx.DirDialog):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):

16
gooey/gui/windows/advanced_config.py

@ -6,7 +6,7 @@ Managed the internal layout for configuration options
import wx import wx
from bson import ObjectId
from wx.lib.scrolledpanel import ScrolledPanel from wx.lib.scrolledpanel import ScrolledPanel
from itertools import chain, izip_longest from itertools import chain, izip_longest
@ -29,11 +29,19 @@ class WidgetContainer(wx.Panel):
self.SetSizer(self.container) self.SetSizer(self.container)
def populate(self, widgets): def populate(self, widgets):
for w in widgets:
widget_class = getattr(components, w.type)
self.widgets.append(widget_class(self, w.title, w.msg))
for index, widget in enumerate(widgets):
widget_class = getattr(components, widget.type)
widget_instance = widget_class(self, widget.title, widget.help)
# widget_instance.bind(wx.EVT_TEXT, self.publish_change)
self.widgets.append(widget_instance)
self.layout() self.layout()
def publish_change(self, evt):
evt.Skip()
def get_values(self):
return [x.get_value() for x in self.widgets]
def layout(self): def layout(self):
STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING)

3
gooey/gui/windows/base_window.py

@ -258,6 +258,9 @@ class BaseWindow(wx.Frame):
dlg.Destroy() dlg.Destroy()
return result return result
def show_missing_args_dialog(self):
self.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
if __name__ == '__main__': if __name__ == '__main__':
pass pass

1
gooey/python_bindings/config_generator.py

@ -32,6 +32,7 @@ def create_from_parser(parser, source_path, **kwargs):
'progress_expr': kwargs.get('progress_expr'), 'progress_expr': kwargs.get('progress_expr'),
'disable_progress_bar_animation': kwargs.get('disable_progress_bar_animation'), 'disable_progress_bar_animation': kwargs.get('disable_progress_bar_animation'),
'disable_stop_button': kwargs.get('disable_stop_button'), 'disable_stop_button': kwargs.get('disable_stop_button'),
'group_by_type': kwargs.get('group_by_type', True)
} }
if show_config: if show_config:

Loading…
Cancel
Save