From Dabo Wiki
Jump to: navigation, search


The PreferenceDialog class is designed to make it easy for you to present users with options that they can configure. It ties in very nicely with the PreferenceManager class, so you can use a unified approach to managing user preferences and settings.

The PreferenceDialog class is a dialog with one or more pages that contain controls that are used to adjust preferences and settings for your application. Typically, you group related settings onto their own page to make it easy for your users to find what they want to set.

To do this, create pages using the addCategory() method, and then populate those pages with controls that are bound to the preference settings you wish to manage. addCategory() takes two parameters: the caption (required), and the position (optional; default is to append to the end).


Here is a very simple example; we will discuss the code below:

import wx
import dabo
from dabo.ui.dialogs.PreferenceDialog import PreferenceDialog

class CustomPrefDlg(PreferenceDialog):
  def addPages(self):
    # Set the preference keys that we will be using
    pm = self.PreferenceManager
    fontKey = pm.fonts
    checkChangesKey = pm.checkChanges
    # Create one page for font prefs, another for updates
    fontPage = self.addCategory("Fonts")
    # Add controls to the font page.
    chk = dabo.ui.dCheckBox(fontPage, Caption="Bold?", 
      DataSource=fontKey, DataField="bold")
    # Add whatever other controls you need...

    # Add controls to the changes page.
    changesPage = self.addCategory("Change Management")
    chc = dabo.ui.dDropdownList(changesPage, Choices=["Yes", "No", "Maybe"],
      DataSource=checkChangesKey, DataField="checkForChanges")
    # Add whatever other controls you need...

class TestForm(dabo.ui.dForm):
  def afterInit(self):
    lbl = dabo.ui.dLabel(self, Caption="Preference Manager Demo\n" +
      "Select 'Preferences' from the menu.", WordWrap=True)
    self.Sizer.append(lbl, halign="center")

if __name__ == '__main__':
  app = dabo.dApp(BasePrefKey = "demo.PrefDialog")
  app.MainFormClass = TestForm
  app.PreferenceDialogClass = CustomPrefDlg

Defining the Custom Dialog class

The only method we typically have to override is the addPages() method. As the name suggests, this is where we add the pages we need for our app's settings. In this example, we only are using two: one for font settings, and one for tracking changes.

Preference Objects

This is also a good illustration of how to use the PreferenceManager object. You simply define attributes of that object, and they are automagically added to it. In this example, we use pm as the name of the app's PreferenceManager object, which has a path of demo.PrefDialog, which is the app's BasePrefKey. We then create keys off of it named fonts and checkChanges by simply referencing those keys as attributes of pm.

One cool thing about preference objects is that they can either persist their value as soon as you set it, or they can cache those changes until you either call their persist() method (to save) or their cancel() method to discard the changes. This behavior is controlled by the AutoPersist property of the preference object, but we don't have to worry about dealing with that here. Simply add any preference keys whose values you want to manage to the PreferenceDialog's preferenceKeys list, and their persistence settings will be handled for you. If the user cancels out of the dialog, none of the changes they made will be saved.

Adding the Pages

Now that we have the preference information set, we call the addCategory() method to create the page for the font settings, passing in the caption "Fonts". This method adds the page to the dialog's paged control, and returns a reference to the newly-created page. We then use as the parent for the controls used for the font settings. To keep things simple, we have a single setting, called bold. In a real app, you'd probably have default font faces, sizes, etc., but this will do for this demo. What's critical to note are the DataSource and DataField properties: DataSource is set to the fontKey object we defined, and DataField is set to bold. This will automagically add the subkey of bold to the fontKey preference object (if it doesn't already exist), making the full key path for this demo.prefDialog.fonts.bold. Also, if there already is a setting saved for this key, it will be retrieved, and the control's Value will be set accordingly. We repeat this for the change management page, but this time we use a dropdown list to present the user with 3 options. This value will be saved to the preference database when the user clicks OK.

Defining the Form

The form really doesn't do anything in this demo, so all we do is add a descriptive label.

Setting Up the Application

There are a few basic properties of the application object that we need to set:

  • BasePrefKey: This is the unique name under which your preferences are saved. For this demo I chose a subkey of prefDialog off of a main demo key.
  • MainFormClass: the class used by the app for its startup form.
  • PreferenceDialogClass: The class to display when the user selects the Preferences menu item. In this example, it is the CustomPrefDlg class we defined.