This tutorial shows how to add an options box to your application. We will be extending the example code created in the menus tutorial (since the menu is needed to access the options box).
The options menu item defined in the last tutorial doesn't work yet, because we haven't defined any options. As with the menus, the first thing to do is tell ROX-Lib where we're loading and saving our options. Options live in groups, but normally we just use setup_app_options() to create a single default group:
from rox import g, Menu rox.setup_app_options('MiniClock') import clock rox.app_options.notify()
Notice that we initialise the options before importing the clock module. This is because the clock module is going to add options to the default group. After all options have been created (eg, by importing all the modules that define options), you must call notify() to let everyone know about changes from the default values (app_options is the default group created by setup_app_options).
Now create a single option in clock.py:
from rox import g from rox.options import Option format = Option('format', 'short')
The first argument to the Option constructor is the name of the option (used in the save file), and the second is the default value.
Now we need to define the layout of the options box. ROX-Lib makes this very easy. Create a new file called Options.xml:
<options> <section title='Display'> <frame label='Time format'> <radio-group name='format'> <radio label='Short format' value='short'>Just show the time</radio> <radio label='Long format' value='long'>Show the time and date</radio> </radio-group> </frame> </section> </options>
'Display' is the section label, and is only shown if you define more than one section. Frames are used to group options visually under a heading. The element creates a list of radio-buttons for the option named 'format'. Each of the elements inside it corresponds to one choice, giving the label for the button, the value and the tooltip with a longer explaination of the option.
See the OptionsBox module documentation for a full description of each option type.
If you try it now, you'll find you have a working options box, complete with a Revert button, which will save your settings between runs. Now we just need to actually change the display as the option is changed...
Getting the value of an option is as simple as option.value. Values are always strings, but you can use option.int_value for integer options to save converting them (if value isn't a valid number then int_value is -1).
def update_time(self): if format.value == 'short': self.set_text(time.strftime('%H:%M.%S')) else: self.set_text(time.ctime()) return 1
However, this doesn't update instantly when the option is changed (the user has to wait a full second for the next update). This isn't too bad, but in other cases the wait could be longer. We can get notified when an option is changed like this:
def __init__(self): g.Label.__init__(self, '') self.update_time() # Add notify callback rox.app_options.add_notify(self.options_changed) timeout = g.timeout_add(1000, self.update_time) def destroyed(self): g.timeout_remove(timeout) # Remove callback rox.app_options.remove_notify(self.options_changed) self.connect('destroy', destroyed)
When any option is changed, the options_changed method is called. You can use the has_changed flag to see if any particular option has changed. If several options are changed at once (eg, when the user clicks Revert) then options_changed will only be called once, at the end.
def options_changed(self): if format.has_changed: self.update_time()
You should now find that changing the option updates the display instantly.