<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Mouse Vs. The Python &#187; ConfigObj</title>
	<atom:link href="http://www.blog.pythonlibrary.org/tag/configobj/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blog.pythonlibrary.org</link>
	<description>Python Programming from the Frontlines</description>
	<lastBuildDate>Tue, 27 Jul 2010 14:59:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Generating a Dialog from a File</title>
		<link>http://www.blog.pythonlibrary.org/2010/01/20/generating-a-dialog-from-a-file/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/01/20/generating-a-dialog-from-a-file/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 02:34:35 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wxPython]]></category>
		<category><![CDATA[ConfigObj]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=462</guid>
		<description><![CDATA[A few days ago, I wrote an article about using ConfigObj with wxPython. The first question I was asked about the article regarded using a configuration file to generate the dialog. I thought this was an interesting idea, so I took a stab at implementing that functionality. Personally I think it would be probably be [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, I wrote an <a href="http://www.blog.pythonlibrary.org/2010/01/17/configobj-wxpython-geek-happiness/">article</a> about using ConfigObj with wxPython. The first question I was asked about the article regarded using a configuration file to generate the dialog. I thought this was an interesting idea, so I took a stab at implementing that functionality. Personally I think it would be probably be better to just create the dialog using XRC and use ConfigObj to help manage which dialog file is loaded that way. However, this was an intriguing exercise to me and I think you&#8217;ll find it enlightening too.<span id="more-462"></span></p>
<p>DISCLAIMER: This is a total hack and may or may not serve you needs. I give various suggestions for expanding the example though, so I hope it&#8217;s helpful!</p>
<p>Now that that&#8217;s out of the way, let&#8217;s create a super simple configuration file. We&#8217;ll call it &#8220;config.ini&#8221; for convenience&#8217;s sake:</p>
<p><b>config.ini</b></p>
<pre>server = Update Server:
username = Username:
password = Password:
update interval = Update Interval:
agency = Agency Filter:
filters = &quot;&quot;
&nbsp;
[Values]
server = http://www.someCoolWebsite/hackery.php
username = &quot;&quot;
password = &quot;&quot;
update interval = 2
agency_choices = Include all agencies except, Include all agencies except, Exclude all agencies except
filters = &quot;&quot;</pre>
<p>This configuration file has two sections: Labels and Values. The <em>Labels </em>section has the labels we will use to create wx.StaticText controls with. The <em>Values </em>section has some sample values we can use for the corresponding text control widgets and one combo box. Note that the <em>agency_choices</em> field is a list. The first item in the list will be the default option in the combo box and the other two items are the real contents of the widget.</p>
<p>Now let&#8217;s take a look at the code that will build the dialog:</p>
<p><b>preferencesDlg.py</b></p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
<span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> PreferencesDialog<span style="color: black;">&#40;</span>wx.<span style="color: black;">Dialog</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Creates and displays a preferences dialog that allows the user to
    change some settings.
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Initialize the dialog
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Dialog</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">'Preferences'</span>, size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">550</span>,<span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">createWidgets</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Create and layout the widgets in the dialog
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        lblSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        valueSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        btnSizer = wx.<span style="color: black;">StdDialogButtonSizer</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        colSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
&nbsp;
        iniFile = <span style="color: #483d8b;">&quot;config.ini&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">config</span> = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>iniFile<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: #008000;">self</span>.<span style="color: black;">config</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Labels&quot;</span><span style="color: black;">&#93;</span>
        values = <span style="color: #008000;">self</span>.<span style="color: black;">config</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Values&quot;</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">widgetNames</span> = values
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            value = labels<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span>
            lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=value<span style="color: black;">&#41;</span>
            lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
            lblSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> values:
            <span style="color: #ff7700;font-weight:bold;">print</span> key
            value = values<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>value, <span style="color: #008000;">list</span><span style="color: black;">&#41;</span>:
                default = value<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
                choices = value<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span>
                cbo = wx.<span style="color: black;">ComboBox</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value=value<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>,
                                  size=wx.<span style="color: black;">DefaultSize</span>, choices=choices,
                                  style=wx.<span style="color: black;">CB_DROPDOWN</span>|wx.<span style="color: black;">CB_READONLY</span>,
                                  name=key<span style="color: black;">&#41;</span>
                valueSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>cbo, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value=value, name=key<span style="color: black;">&#41;</span>
                valueSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">EXPAND</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
&nbsp;
        saveBtn = wx.<span style="color: black;">Button</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_OK</span>, label=<span style="color: #483d8b;">&quot;Save&quot;</span><span style="color: black;">&#41;</span>
        saveBtn.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_BUTTON</span>, <span style="color: #008000;">self</span>.<span style="color: black;">onSave</span><span style="color: black;">&#41;</span>
        btnSizer.<span style="color: black;">AddButton</span><span style="color: black;">&#40;</span>saveBtn<span style="color: black;">&#41;</span>
&nbsp;
        cancelBtn = wx.<span style="color: black;">Button</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_CANCEL</span><span style="color: black;">&#41;</span>
        btnSizer.<span style="color: black;">AddButton</span><span style="color: black;">&#40;</span>cancelBtn<span style="color: black;">&#41;</span>
        btnSizer.<span style="color: black;">Realize</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        colSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lblSizer<span style="color: black;">&#41;</span>
        colSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>valueSizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>colSizer, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>btnSizer, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span> | wx.<span style="color: black;">ALIGN_RIGHT</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onSave<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Saves values to disk
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> name <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">widgetNames</span>:
            widget = wx.<span style="color: black;">FindWindowByName</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>widget, wx.<span style="color: black;">ComboBox</span><span style="color: black;">&#41;</span>:
                selection = widget.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                choices = widget.<span style="color: black;">GetItems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                choices.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, selection<span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">widgetNames</span><span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span> = choices
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                value = widget.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">widgetNames</span><span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span> = value
        <span style="color: #008000;">self</span>.<span style="color: black;">config</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">EndModal</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> MyApp<span style="color: black;">&#40;</span>wx.<span style="color: black;">App</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> OnInit<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        dlg = PreferencesDialog<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        dlg.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        dlg.<span style="color: black;">Destroy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = MyApp<span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>To start, we subclass a wx.Dialog and all its <em>createWidgets </em>method. This method will read our config file and use the data therein to create the display. Once the config is read, we loop over the keys in the <em>Labels</em> section and create static text controls as needed. Next, we loop over the values in the other section and use a conditional to check the type of widget. In this case, we only care about wx.TextCtrl and wx.Combobox. This is where ConfigObj helps since it actually can typecast some of the entries in our configuration file. If you use a configspec, you can get even more granular and that may be the way you&#8217;ll want to go to extend this tutorial. Note that for the text controls and combo box, I set the name field. This is important for saving the data, which we&#8217;ll be seeing in just a moment.</p>
<p>Anyway, in both loops, we use vertical BoxSizers to hold our widgets. You may want to swap this for a GridBagSizer or FlexGridSizer for your specialized interface. I personally really like BoxSizers. I also used a StdDialogButtonSizer for the buttons at the suggestion of Steven Sproat (<a href="https://launchpad.net/whyteboard">Whyteboard</a>). If you use the correct standard ids for the buttons, this sizer will place them in the right order in a cross-platform way. It&#8217;s quite handy, although it doesn&#8217;t take many arguments. Also note that the <a href="http://www.wxpython.org/docs/api/wx.StdDialogButtonSizer-class.html">documentation </a>for this sizer implies you can specify the orientation, but you really cannot. I spoke with Robin Dunn (creator of wxPython) about this issue on IRC and he said that <a href="http://epydoc.sourceforge.net/">epydoc</a> was grabbing the wrong docstring.</p>
<p>The next method that we care about is <em>onSave</em>. Here is where we save whatever the user has entered. Earlier in the program, I grabbed the widget names from the configuration and we loop over those now. We call wx.FindWindowByName to find the widget by name. Then we use <em>isinstance</em> again to check what kind of widget we have. Once that&#8217;s done, we grab the value that the widget holds using GetValue and assign that value to the correct field in our configuration. When the loop finishes, we write the data to disk. <strong>Immediate improvement alert: I have no validation here at all! This is something for you to do to extend this example</strong>. The last step is to call EndModal(0) to close the dialog and, in turn, the application.</p>
<p>Now you know the basics of generating a dialog from a configuration file. I think using some kind of dictionary with widget type names (probably in strings) might be an easy way to make this script work with other widgets. Use your imagination and let me know what you come up with.</p>
<p><em>Note: All code tested on Windows XP with Python 2.5, ConfigObj 4.6.0, and Validate 1.0.0.</em></p>
<p><strong>Further Reading</strong></p>
<ul>
<li><a href="http://www.voidspace.org.uk/python/articles/configobj.shtml">ConfigObj Tutorial</a></li>
<li><a href="http://wiki.wxpython.org/UsingXmlResources">XRC and wxPython</a></li>
<li><a href="http://www.wxpython.org/docs/api/wx.Dialog-class.html">wx.Dialog
<p>Documentation</a></li>
</ul>
<p><strong>Downloads</strong></p>
<ul>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/dialog_from_config.zip'>dialog_from_config.zip</a></li>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/dialog_from_config.tar'>dialog_from_config.tar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/01/20/generating-a-dialog-from-a-file/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ConfigObj + wxPython = Geek Happiness</title>
		<link>http://www.blog.pythonlibrary.org/2010/01/17/configobj-wxpython-geek-happiness/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/01/17/configobj-wxpython-geek-happiness/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 14:41:57 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wxPython]]></category>
		<category><![CDATA[ConfigObj]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=446</guid>
		<description><![CDATA[I recently starting using Michael Foord&#8217;s ConfigObj for one of our internal wxPython applications at work. When I wrote my other ConfigObj tutorial, I wanted to show you how I was using ConfigObj with my preferences dialog, but I didn&#8217;t want all my posts to include wx. In this article, I&#8217;ll just show you how [...]]]></description>
			<content:encoded><![CDATA[<p>I recently starting using <a href="http://www.voidspace.org.uk/">Michael Foord&#8217;s</a> <a href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> for one of our internal <a href="http://www.wxpython.org">wxPython </a>applications at work. When I wrote my other ConfigObj <a href="http://www.blog.pythonlibrary.org/2010/01/01/a-brief-configobj-tutorial/">tutorial</a>, I wanted to show you how I was using ConfigObj with my preferences dialog, but I didn&#8217;t want all my posts to include wx. In this article, I&#8217;ll just show you how easy it is to add a new preference setting in ConfigObj without wiping out your original ones and how to load and save them with a wxPython dialog. Now, let&#8217;s get to it!<span id="more-446"></span></p>
<p>First we&#8217;ll create a simple controller for creating and accessing our configuration file with ConfigObj:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> wx
<span style="color: #ff7700;font-weight:bold;">from</span> wx.<span style="color: black;">lib</span>.<span style="color: black;">buttons</span> <span style="color: #ff7700;font-weight:bold;">import</span> GenBitmapTextButton
&nbsp;
appPath = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
inifile = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>appPath, <span style="color: #483d8b;">&quot;example.ini&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> CloseBtn<span style="color: black;">&#40;</span>GenBitmapTextButton<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Creates a reusuable close button with a bitmap
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent, label=<span style="color: #483d8b;">&quot;Close&quot;</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">16</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
        img = wx.<span style="color: black;">Bitmap</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;%s<span style="color: #000099; font-weight: bold;">\i</span>mages<span style="color: #000099; font-weight: bold;">\c</span>ancel.png&quot;</span> <span style="color: #66cc66;">%</span> appPath<span style="color: black;">&#41;</span>
        GenBitmapTextButton.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent, wx.<span style="color: black;">ID_CLOSE</span>, img,
                                     label=label, size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">110</span>, <span style="color: #ff4500;">50</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.someCoolWebsite/hackery.php&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'agency filter'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'include'</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'filters'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>inifile<span style="color: black;">&#41;</span>:
        createConfig<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>inifile<span style="color: black;">&#41;</span></pre>
<p>This piece of code is pretty straightforward. In the <em>createConfig</em> function, it creates an &#8220;example.ini&#8221; file in the same directory as the one that this script is run from. The config file gets six fields, but no sections. In the <em>getConfig</em> function, the code checks for the existence of the configuration file and creates it if it does not exist. Regardless, the function returns a ConfigObj object to the caller. We&#8217;ll put this script into &#8220;controller.py&#8221;. Now we&#8217;ll subclass the wx.Dialog class to create a preferences dialog.</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># -----------------------------------------------------------</span>
<span style="color: #808080; font-style: italic;"># preferencesDlg.py</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Created 10/20/2009 by mld</span>
<span style="color: #808080; font-style: italic;"># -----------------------------------------------------------</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> controller
<span style="color: #ff7700;font-weight:bold;">import</span> wx
<span style="color: #ff7700;font-weight:bold;">from</span> wx.<span style="color: black;">lib</span>.<span style="color: black;">buttons</span> <span style="color: #ff7700;font-weight:bold;">import</span> GenBitmapTextButton
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> PreferencesDialog<span style="color: black;">&#40;</span>wx.<span style="color: black;">Dialog</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Creates and displays a preferences dialog that allows the user to
    change some settings.
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Dialog</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">'Preferences'</span>, size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">550</span>,<span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        appPath = controller.<span style="color: black;">appPath</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># ---------------------------------------------------------------------</span>
        <span style="color: #808080; font-style: italic;"># Create widgets</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
        serverLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Update Server:&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">serverTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">serverTxt</span>.<span style="color: black;">Disable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        usernameLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Username:&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">usernameTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">usernameTxt</span>.<span style="color: black;">Disable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        passwordLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Password:&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">passwordTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;&quot;</span>, style=wx.<span style="color: black;">TE_PASSWORD</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">passwordTxt</span>.<span style="color: black;">Disable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        updateLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Update Interval:&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">updateTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
        minutesLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;minutes&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
        agencyLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Agency Filter:&quot;</span><span style="color: black;">&#41;</span>
        choices = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Include all agencies except&quot;</span>, <span style="color: #483d8b;">&quot;Exclude all agencies except&quot;</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span> = wx.<span style="color: black;">ComboBox</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;Include all agencies except&quot;</span>,
                                     <span style="color: #008000;">None</span>, wx.<span style="color: black;">DefaultSize</span>, choices, wx.<span style="color: black;">CB_DROPDOWN</span>|wx.<span style="color: black;">CB_READONLY</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span>.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">filterTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
        img = wx.<span style="color: black;">Bitmap</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;%s/images/filesave.png&quot;</span> <span style="color: #66cc66;">%</span> appPath<span style="color: black;">&#41;</span>
        saveBtn = GenBitmapTextButton<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>, img, <span style="color: #483d8b;">&quot;Save&quot;</span>, size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">110</span>, <span style="color: #ff4500;">50</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        saveBtn.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_BUTTON</span>, <span style="color: #008000;">self</span>.<span style="color: black;">savePreferences</span><span style="color: black;">&#41;</span>
        cancelBtn = controller.<span style="color: black;">CloseBtn</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Cancel&quot;</span><span style="color: black;">&#41;</span>
        cancelBtn.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_BUTTON</span>, <span style="color: #008000;">self</span>.<span style="color: black;">onCancel</span><span style="color: black;">&#41;</span>
&nbsp;
        widgets = <span style="color: black;">&#91;</span>serverLbl, usernameLbl, passwordLbl, updateLbl, agencyLbl, minutesLbl,
                   <span style="color: #008000;">self</span>.<span style="color: black;">serverTxt</span>, <span style="color: #008000;">self</span>.<span style="color: black;">usernameTxt</span>, <span style="color: #008000;">self</span>.<span style="color: black;">passwordTxt</span>, <span style="color: #008000;">self</span>.<span style="color: black;">updateTxt</span>,
                   <span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span>, <span style="color: #008000;">self</span>.<span style="color: black;">filterTxt</span>, saveBtn, cancelBtn<span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> widget <span style="color: #ff7700;font-weight:bold;">in</span> widgets:
            widget.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># ---------------------------------------------------------------------</span>
        <span style="color: #808080; font-style: italic;"># layout widgets</span>
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        updateSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        btnSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        prefSizer = wx.<span style="color: black;">FlexGridSizer</span><span style="color: black;">&#40;</span>cols=<span style="color: #ff4500;">2</span>, hgap=<span style="color: #ff4500;">5</span>, vgap=<span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">AddGrowableCol</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>serverLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">serverTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>usernameLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">usernameTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>passwordLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">passwordTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>updateLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        updateSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">updateTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">RIGHT</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        updateSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>minutesLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>updateSizer<span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>agencyLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALIGN_LEFT</span> | wx.<span style="color: black;">ALIGN_CENTER_VERTICAL</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span>,<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        prefSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">filterTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
&nbsp;
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>prefSizer, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">EXPAND</span>|wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        btnSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>saveBtn, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        btnSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>cancelBtn, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>btnSizer, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span> | wx.<span style="color: black;">ALIGN_RIGHT</span>, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># ---------------------------------------------------------------------</span>
        <span style="color: #808080; font-style: italic;"># load preferences</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">loadPreferences</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> loadPreferences<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Load the preferences and fill the text controls
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        config = controller.<span style="color: black;">getConfig</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        updateServer = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update server'</span><span style="color: black;">&#93;</span>
        username = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span>
        password = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span>
        interval = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span>
        agencyFilter = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'agency filter'</span><span style="color: black;">&#93;</span>
        filters = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'filters'</span><span style="color: black;">&#93;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">serverTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>updateServer<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">usernameTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>username<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">passwordTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>password<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">updateTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>interval<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>agencyFilter<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">filterTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>filters<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onCancel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Closes the dialog
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">EndModal</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> savePreferences<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Save the preferences
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        config = controller.<span style="color: black;">getConfig</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">self</span>.<span style="color: black;">updateTxt</span>.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'agency filter'</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">agencyCbo</span>.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        data = <span style="color: #008000;">self</span>.<span style="color: black;">filterTxt</span>.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;,&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> data:
            filters = <span style="color: black;">&#91;</span>i.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #483d8b;">&quot; &quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> data:
            filters = <span style="color: black;">&#91;</span>i.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            filters = <span style="color: black;">&#91;</span>data<span style="color: black;">&#93;</span>
        text = <span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> filters:
            text += <span style="color: #483d8b;">&quot; &quot;</span> + f
        text = text.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'filters'</span><span style="color: black;">&#93;</span> = text
        config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        dlg = wx.<span style="color: black;">MessageDialog</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #483d8b;">&quot;Preferences Saved!&quot;</span>, <span style="color: #483d8b;">'Information'</span>,
                               wx.<span style="color: black;">OK</span>|wx.<span style="color: black;">ICON_INFORMATION</span><span style="color: black;">&#41;</span>
        dlg.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">EndModal</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">PySimpleApp</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    dlg = PreferencesDialog<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    dlg.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    dlg.<span style="color: black;">Destroy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>The code above creates a basic preferences dialog and loads its configuration from a file using ConfigObj. You can see how that works by reading the code in the <em>loadPreferences</em> method. The only other piece that we care about is how the code saves the preferences when the user changes them. For that, we need to look at the <em>savePreferences</em> method. This is a pretty straightforward method in that all it does is grab the various values from the widgets using wx&#8217;s specific getter functions. There&#8217;s also a conditional that does some minor checking on the filter field. The main reason for that is that in my original program, I use a space as the delimiter and the program needed to convert commas and such to spaces. This code is still a work in progress though as it does not cover all the cases that a user could enter.</p>
<p>Anyway, once we have the values inside the ConfigObj&#8217;s dict-like interface, we write the ConfigObj instance&#8217;s data to file. Then the program displays a simple dialog to let the user know that&#8217;s saved. </p>
<p>Now, let&#8217;s say that our program&#8217;s specifications change such that we need to add or remove a preference. All that is required to do so is to add or delete it in the configuration file. ConfigObj will pick up the changes and we just need to remember to add or remove the appropriate widgets in our GUI. One of the best things about ConfigObj is that it won&#8217;t reset the data in your file, it will just add the changes as appropriate. Give it a try and find out just how easy it is!</p>
<p><em>Note: All code tested on Windows XP with Python 2.5, ConfigObj 4.6.0, and Validate 1.0.0.</em></p>
<p><strong>Downloads</strong></p>
<ul>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/ConfigObj-GUI-Ex.zip'>ConfigObj-GUI-Ex.zip</a></li>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/ConfigObj-GUI-Ex.tar'>ConfigObj-GUI-Ex.tar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/01/17/configobj-wxpython-geek-happiness/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Brief ConfigObj Tutorial</title>
		<link>http://www.blog.pythonlibrary.org/2010/01/01/a-brief-configobj-tutorial/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/01/01/a-brief-configobj-tutorial/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 23:49:09 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ConfigObj]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=416</guid>
		<description><![CDATA[Python comes with a handy module called ConfigParser. It&#8217;s good for creating and reading configuration files (aka INI files). However, Michael Foord (author of IronPython in Action) and Nicola Larosa decided to write their own configuration module called ConfigObj. In many ways, it is an improvement over the standard library&#8217;s module. When I first looked [...]]]></description>
			<content:encoded><![CDATA[<p>Python comes with a handy module called <a href="http://docs.python.org/library/configparser.html">ConfigParser</a>. It&#8217;s good for creating and reading configuration files (aka INI files). However, Michael Foord (author of <a href="http://www.ironpythoninaction.com/">IronPython in Action</a>) and <a href="http://www.teknico.net/">Nicola Larosa</a> decided to write their own configuration module called <a href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a>. In many ways, it is an improvement over the standard library&#8217;s module. When I first looked at ConfigObj&#8217;s home page, I thought it was well documented, but it didn&#8217;t seem to have any fully functional snippets. Since I learn from docs plus examples, I found it harder to get started using ConfigObj when the examples were unavailable. When I started writing this article, I was unaware that Michael Foord has already written his own <a href="http://www.voidspace.org.uk/python/articles/configobj.shtml"> tutorial</a> on the subject; but I had made a promise that I would write my own, so that is what you will get to read today!<span id="more-416"></span></p>
<h2>Getting Started</h2>
<p>First of all you will need to <a href="http://www.voidspace.org.uk/python/modules.shtml#configobj">download ConfigObj</a>. Once you have that downloaded and installed, we can continue. Got it? Then let&#8217;s see what it can do!</p>
<p>To start off, open a text editor and create a file with some contents like this:</p>
<p><code><br />
product = Sony PS3<br />
accessories = controller, eye, memory stick<br />
# This is a comment that will be ignored<br />
retail_price = $400<br />
</code></p>
<p>Save it where ever you like. I&#8217;m going to call mine &#8220;config.ini&#8221;. Now let&#8217;s see how ConfigObj can be used to extract that information:</p>
<p><code><br />
&gt;&gt;&gt; from configobj import ConfigObj<br />
&gt;&gt;&gt; config = ConfigObj(r&quot;path to config.ini&quot;)<br />
&gt;&gt;&gt; config[&quot;product&quot;]<br />
'Sony PS3'<br />
&gt;&gt;&gt; config[&quot;accessories&quot;]<br />
['controller', 'eye', 'memory stick']<br />
&gt;&gt;&gt; type(config[&quot;accessories&quot;])<br />
&lt;type 'list'&gt;<br />
</code></p>
<p>As you can see, ConfigObj uses Python&#8217;s dict API to access the information it has extracted. All you had to do to get ConfigObj to parse the file was to pass the file&#8217;s path to ConfigObj. Now, if the information had been under a section (i.e. [Sony]), then you would have had to do pre-pend everything with ["Sony"], like this: config["Sony"]["product"]. Also take note that the &#8220;accessories&#8221; section was returned as a list of strings. ConfigObj will take any valid line with a comma-separated list and return it as a Python list. You can also create multi-line strings in the config file as long as you enclose them with triple single or double quotes. </p>
<p>If you need to create a sub-section in the file, then use extra square brackets. For example, [Sony] is the top section, [[Playstation]] is the sub-section and [[[PS3]]] is the sub-section of the sub-section. You can create sub-sections up to any depth. For more information on the formatting of the file, I recommend the documentation linked to above.</p>
<p>Now we&#8217;ll do the reverse and create the config file programmatically.</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>As you can see, all it took was 8 lines of code. In the code above, we create a function and pass it the path for our config file. Then we create a ConfigObj object and set its <em>filename</em> property. To create the section, we create an empty dict with the name &#8220;Sony&#8221;. Then we pre-pend each line of the sections contents in the same way. Finally, we call our config object&#8217;s <em>write</em> method to write the data to the file. </p>
<h2>Using a configspec</h2>
<p>ConfigObj also provides a way to validate your configuration files using a <em>configspec</em>. When I mentioned that I was going to write this article, Steven Sproat (creator of <a href="https://launchpad.net/whyteboard">Whyteboard</a>) volunteered his <a href="http://bazaar.launchpad.net/~sproaty/whyteboard/development/annotate/head%3A/utility.py">configspec code</a> as an example. I took his specification and used it to create a default config file. In this example, we use Foord&#8217;s <a href="http://www.voidspace.org.uk/python/validate.html">validate</a> module to do the validation. I don&#8217;t think it&#8217;s included in your ConfigObj download, so you may need to download it as well. Now, let&#8217;s take a look at the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj, validate
&nbsp;
cfg = <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
bmp_select_transparent = boolean(default=False)
canvas_border = integer(min=10, max=35, default=15)
colour1 = list(min=3, max=3, default=list('280', '0', '0'))
colour2 = list(min=3, max=3, default=list('255', '255', '0'))
colour3 = list(min=3, max=3, default=list('0', '255', '0'))
colour4 = list(min=3, max=3, default=list('255', '0', '0'))
colour5 = list(min=3, max=3, default=list('0', '0', '255'))
colour6 = list(min=3, max=3, default=list('160', '32', '240'))
colour7 = list(min=3, max=3, default=list('0', '255', '255'))
colour8 = list(min=3, max=3, default=list('255', '165', '0'))
colour9 = list(min=3, max=3, default=list('211', '211', '211'))
convert_quality = option('highest', 'high', 'normal', default='normal')
default_font = string
default_width = integer(min=1, max=12000, default=640)
default_height = integer(min=1, max=12000, default=480)
imagemagick_path = string
handle_size = integer(min=3, max=15, default=6)
language = option('English', 'English (United Kingdom)', 'Russian', 'Hindi', default='English')
print_title = boolean(default=True)
statusbar = boolean(default=True)
toolbar = boolean(default=True)
toolbox = option('icon', 'text', default='icon')
undo_sheets = integer(min=5, max=50, default=10)
&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file using a configspec
    and validate it against a Validator object
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    spec = cfg.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>path, configspec=spec<span style="color: black;">&#41;</span>
    validator = validate.<span style="color: black;">Validator</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">validate</span><span style="color: black;">&#40;</span>validator, <span style="color: #dc143c;">copy</span>=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;config.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>If you go and look at Steven&#8217;s original configspec, you&#8217;ll notice I shortened his list of languages quite a bit. I did this to make the code easier to read. Anyway, the <a href="http://www.voidspace.org.uk/python/configobj.html#configspec">configspec</a> allows the programmer the ability to specify what types are returned for each line in the configuration file. It also can be used to set a default value and a min and max values (among other things). If you run the code above, you will see a &#8220;config.ini&#8221; file generated in the current working directory that has just the default values. If the programmer didn&#8217;t specify a default, then that line isn&#8217;t even added to the configuration. </p>
<p>Let&#8217;s take a closer look at what&#8217;s going on just to make sure you understand. In the <em>createConfig</em> function, we create a <em>ConfigObj </em>method be passing in the file path and setting the configspec. Note that the configspec can also be a normal text file or a python file rather than the string that is in this example. Next, we create a <em>Validator</em> object. Normal usage is to just call <em>config.validate(validator)</em>, but in this code I set the <em>copy </em>argument to <em>True</em> so that I could create a file. Otherwise, all it would do is validate that the file I passed in fit the configspec&#8217;s rules. Finally I set the config&#8217;s <em>filename</em> and write the data out. </p>
<h2>Wrapping Up</h2>
<p>Now you know just enough to get you started on the ins and outs of ConfigObj. I hope you&#8217;ll find it as helpful as I have. There&#8217;s lots more to learn, so be sure to check out some of the links below.</p>
<p><em>Note: All code tested on Windows XP with Python 2.5, ConfigObj 4.6.0, and Validate 1.0.0.</em></p>
<p><strong>Further Reading</strong></p>
<ul>
<li><a href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj Official Documentation</a></li>
<li><a href="http://www.voidspace.org.uk/python/validate.html">Validate Official Documentation</a></li>
<li><a href="http://www.voidspace.org.uk/python/articles/configobj.shtml">Michael Foord&#8217;s ConfigObj Tutorial</a></li>
</ul>
<p><strong>Download the Source</strong></p>
<ul>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/configObjTut.zip'>configObjTut.zip</a></li>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/01/configObjTut.tar'>configObjTut.tar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/01/01/a-brief-configobj-tutorial/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.635 seconds -->
