Skip to content

Instantly share code, notes, and snippets.

@matthewryanscott
Created June 30, 2012 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewryanscott/3021983 to your computer and use it in GitHub Desktop.
Save matthewryanscott/3021983 to your computer and use it in GitHub Desktop.
Component uninitialized; attr changes do not propagate as expected
# System:
# OSX 10.7.4
# Qt 4.8.0
# PySide 1.1.1
from enaml.stdlib.radio_group import RadioGroup
DEFAULT_TRIGGER_METHOD_NAME = 'request_refresh_task'
enamldef Main(MainWindow):
id: main
attr trigger_methods = {
# Triggering the widget_needs_updating event
# immediately after widget.main_component is created
# results in that component being uninitialized
# every time.
'directly': lambda main: main.widget_needs_updating(),
# Using call_on_main resulted in widget.main_component
# being uninitialized at the time of event trigger
# in 100% of cases.
# https://github.com/enthought/enaml/blob/master/enaml/components/abstract_application.py
'call_on_main': lambda main: main.toolkit.app.call_on_main(main.widget_needs_updating),
# Using a timer with 0ms timeout is not reliable.
# In than 50% of cases, widget.main_component is initialized
# by the time we trigger the widget_needs_updating event,
# but occasionally it is not.
# https://github.com/enthought/enaml/blob/master/enaml/components/abstract_application.py
'timer': lambda main: main.toolkit.app.timer(0, main.widget_needs_updating),
# Using toolkit.app.schedule with a priority >= 50
# appears to result in desired behavior in 100% of cases.
# If priority is < 50, widget.main_component will
# always be uninitialized.
# https://github.com/enthought/enaml/blob/master/enaml/components/abstract_application.py
'schedule49': lambda main: main.toolkit.app.schedule(main.widget_needs_updating, priority=49),
'schedule50': lambda main: main.toolkit.app.schedule(main.widget_needs_updating, priority=50),
'schedule100': lambda main: main.toolkit.app.schedule(main.widget_needs_updating, priority=100),
# We use request_refresh_task to reliably trigger the event
# after widget.main_component is initialized.
# Works in 100% of cases, and seems semantically appropriate.
# http://docs.enthought.com/enaml/api_ref/widgets/enaml.core.base_component.BaseComponent.html#enaml.core.base_component.BaseComponent.request_refresh_task
'request_refresh_task': lambda main: main.request_refresh_task(main.widget_needs_updating),
}
attr current_trigger_method_name = DEFAULT_TRIGGER_METHOD_NAME
attr current_trigger_method << trigger_methods[current_trigger_method_name]
attr counter = 0
counter ::
if widget.main_component:
current_trigger_method(main)
initialized ::
main.counter = 0
increment.clicked()
event widget_needs_updating ::
widget.main_component.counter = counter
print 'widget.main_component.counter ==', widget.main_component.counter
print 'widget.main_component.initialized ==', widget.main_component.initialized
print
Container:
CustomWidget:
id: widget
initialized ::
self.recreate_requested()
PushButton:
text = 'Regenerate'
clicked ::
widget.recreate_requested()
current_trigger_method(main)
PushButton:
id: increment
text = 'Increment'
clicked :: main.counter += 1
RadioGroup:
items = sorted(trigger_methods.keys())
orientation = 'vertical'
selected_index = items.index(current_trigger_method_name)
selected_label >> main.current_trigger_method_name
enamldef CustomWidget(Container):
padding = (0, 0, 0, 0)
attr main_component = None
event recreate_requested ::
self.main_component = EmbeddedWidget()
Include:
components << [main_component] if main_component is not None else []
enamldef EmbeddedWidget(Container):
attr counter = None
attr label << str(counter)
label ::
editor.set_text(label)
TextEditor:
id: editor
read_only = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment