<?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>learning python &#187; reference</title>
	<atom:link href="http://www.learningpython.com/category/python/reference/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Mon, 26 Apr 2010 01:21:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TextWidget &#8211; A simple text class for PyGame</title>
		<link>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/</link>
		<comments>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/#comments</comments>
		<pubDate>Thu, 14 Dec 2006 03:47:28 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[TextWidget]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=49</guid>
		<description><![CDATA[
			
				
			
		
Introduction
All right, this is just a little tutorial about working with text in pygame.  Now, this isn&#8217;t the only way to work with text, there are many other methods to do this, in fact much of the time you&#8217;ll probably end up using images for interactive text.  So this is mainly meant to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F12%2F13%2Ftextwidget-a-simple-text-class-for-pygame%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F12%2F13%2Ftextwidget-a-simple-text-class-for-pygame%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<h2>Introduction</h2>
<p>All right, this is just a little tutorial about working with text in pygame.  Now, this isn&#8217;t the only way to work with text, there are many other methods to do this, in fact much of the time you&#8217;ll probably end up using images for interactive text.  So this is mainly meant to serve as a informative guide to using the text features in PyGame, and how you <em>might</em> want to implement them.</p>
<p>The TextWidget object discussed in this tutorial can be used to make something that looks like this (but you&#8217;d probably want to use better looking colours):</p>
<p><embed src="http://www.learningpython.com/flash/textwidget.swf" width="320" height="240" play="true" loop="True" quality="low" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"><br />
</embed></p>
<p>The full source and necessary files for this tutorial can be downloaded <a href="http://www.learningpython.com/sources/TextWidget.tar.gz">here</a>.</p>
<p>So, in order to make this easy to use and very reusable we&#8217;re going to create a class called TextWidget in a file called TextWidget.py.  The top of the file is full of the standard python initialization:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#! /usr/bin/env python

</span><span class="hl-reserved">import </span><span class="hl-identifier">pygame

TEXT_WIDGET_CLICK</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals</span><span class="hl-default">.</span><span class="hl-identifier">USEREVENT</span><span class="hl-default"> + </span><span class="hl-number">1</span></pre></div></div>
<p>We import pygame and then we set a define TEXT_WIDGET_CLICK , which will be used later on as the event type when the TextWidget is clicked on.</p>
<p>The next thing to do is define the actual class:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>Now the astute among you will recognize that this is a &#8220;new-style&#8221; python class (i.e. it&#8217;s base class is the object class) rather then a classic class.  I did this for two reasons:</p>
<ol>
<li>I wanted to be able to control what happens when people set values in the class.  So, for example, if you set the size of the font to be something, I wanted the display to automatically adjust to reflect the new size.</li>
<li>I haven&#8217;t really used new-style classes before so I thought I&#8217;d try them out.</li>
</ol>
<p><strong>Note:</strong> If you are unfamiliar with properties or new-style classes you might want to give this a read: </p>
<ul>
<li><a href="http://www.python.org/download/releases/2.2.3/descrintro">Unifying types and classes in Python 2.2</a></li>
<li><a href="http://www.geocities.com/foetsch/python/new_style_classes.htm#property">Introduction To New-Style Classes In Python</a></li>
</ul>
<p><span id="more-49"></span></p>
<p>As a result of number one above I&#8217;m going to use <a href="http://www.python.org/download/releases/2.2.3/descrintro/#property">properties</a> for those values that I want to perform some &#8220;automatic processing&#8221; when their values changes.</p>
<p>The properties that I am going to define are as follows:</p>
<ul>
<li>text &#8211; The string of text that the TextWidget will display.</li>
<li>colour &#8211; The colour that the text will be rendered in.</li>
<li>size &#8211; The size of the font.</li>
<li>font_filename &#8211; The filename of the font to use for the text (probably something returned by <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.get_fonts">pygame.font.get_fonts</a> or <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.match_font">pygame.font.match_font</a>.</li>
<li>highlight &#8211; A boolean, whether the font is highlighted or not. (i.e. whether the mouse is over the TextWidget.</li>
<li>highlight_cursor &#8211; A boolean that controls whether or not to show a hand cursor when the TextWidget is in highlight mode.  If the TextWidget is not supposed to be interactive you should set this to False.</li>
</ul>
<p>There are also a few other important members of the class, but since they are not python properties I have listed them separately:</p>
<ul>
<li>__hand &#8211; A hand cursor, which can optionally by displayed when the cursor hovers over the text.</li>
<li>dirty &#8211; A boolean, that lets the TextWidget know whether or not it needs to draw.  If dirty = False it will not draw, if dirty = True it will draw.</li>
<li>bold_rect &#8211; pygame.Rect &#8211; A rectangle that is equal to the size of the highlighted text.  It is used so that when we move from highlighted to non-highlighted text all of the text is erased.  Otherwise if we just drew updated the normal rectangle, all of the highlighted text that was outside of it would not be redrawn.</li>
<li>rect – pygame.Rect – The Rectangle where the text will be drawn.  Use this to position your text, but its height and width will always be controlled by the text and the font.</li>
<li>highlight_increase &#8211; Boolean whether or not the text should increase in size when the cursor is over it.  If the text is &#8220;non-interactive&#8221; then this should be False.</li>
<li>tracking &#8211; Boolean whether or not the TextWidget is tracking a mouse click.  Used so that we can tell whether or not a true &#8220;click&#8221; has occurred.  A true click is one where both the mouse-down and mouse-up events occur on the TextWidget.</li>
</ul>
<p>To hopefully make the functionality of the TextWidget a bit clearer here is some non-highlighted text and then some highlighted text:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/text_01.png" alt="Python pygame text" border="0" /></p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/text_02.png" alt="Python pygame text" border="0" /></p>
<h2>The Code</h2>
<p>Now we get to the heart of the actual python\PyGame code, where we actually create a working TextWidget object.</p>
<p>So we&#8217;ll start off at the top of the file and then work out way downwards in a linear manner.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is a helper class for handling text in PyGame.  It performs 
    some basic highlighting and tells you when the text has been clicked.
    This is just one of the many ways to handle your text.
    This is a new-style class and I am somewhat new to them so hopefully it 
    all works.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Hand Cursor
    </span><span class="hl-identifier">__hand_cursor_string</span><span class="hl-default"> = </span><span class="hl-brackets">(
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     XX         </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X        </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..XXXXX    </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X..X..X.XX  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string"> XX X..X..X.X.X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">X..XX.........X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">X...X.........X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string"> X.....X.X.X..X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">  X....X.X.X..X </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">  X....X.X.X.X  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">   X...X.X.X.X  </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">    X.......X   </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     X....X.X   </span><span class="hl-quotes">&quot;</span><span class="hl-code">,
    </span><span class="hl-quotes">&quot;</span><span class="hl-string">     XXXXX XX   </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">__hcurs</span><span class="hl-default">, </span><span class="hl-identifier">__hmask</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">cursors</span><span class="hl-default">.</span><span class="hl-builtin">compile</span><span class="hl-brackets">(</span><span class="hl-identifier">__hand_cursor_string</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">.</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">X</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">__hand</span><span class="hl-default"> = </span><span class="hl-brackets">((</span><span class="hl-number">16</span><span class="hl-code">, </span><span class="hl-number">16</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">__hcurs</span><span class="hl-code">, </span><span class="hl-identifier">__hmask</span><span class="hl-brackets">)</span></pre></div></div>
<p>The above code is where we create the hand cursor that we will use if the person turns on the highlight_cursor.  We first define what the cursor will look like as explained in the <a href="http://www.pygame.org/docs/ref/cursors.html#pygame.cursors.compile">PyGame cursor documentation</a>.</p>
<p>The next step is to create all of our properties, now this code may seem a bit complicated, especially since it deals with functions that we have not created yet, but as I explain it, it could become clearer and clearer.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Text
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_text</span><span class="hl-code"> != </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text</span><span class="hl-default"> = </span><span class="hl-identifier">text
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()
</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_text</span><span class="hl-code">, </span><span class="hl-identifier">__set_text</span><span class="hl-brackets">)</span></pre></div></div>
<p>The above code creates the TextWidget.text property.  The __get_text() function is used to get the text property which is represented by the __m_text variable, and the __set_text() function is the function that is called when you want to set the value of the text property.</p>
<p>What you will notice about the __set_text() function is that it first tests to see if the text that we are setting (text) is any different then the current text (__m_text) if it isn&#8217;t any different we don&#8217;t do anything.  </p>
<p>However if it is different we set __m_text and we call update_surface().  update_surface() is a member function that I will explain in more detail later, but for now all you need to know is that it updates what the widget will display.  So since we changed the text we want the widget to update and display the new text.</p>
<p>You can probably see why I wanted to use new-style classes and properties now.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Colour
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_colour</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_colour</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">colour</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_colour</span><span class="hl-code"> != </span><span class="hl-identifier">colour</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour</span><span class="hl-default"> = </span><span class="hl-identifier">colour
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()
</span><span class="hl-identifier">colour</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_colour</span><span class="hl-code">, </span><span class="hl-identifier">__set_colour</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next is the colour property, as you can see it&#8217;s basically identical to the text property, so I won&#8217;t bother explaining it.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Size
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_size</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_size</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_size</span><span class="hl-code"> != </span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size</span><span class="hl-default"> = </span><span class="hl-identifier">size
        self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_size</span><span class="hl-code">, </span><span class="hl-identifier">__set_size</span><span class="hl-brackets">)</span></pre></div></div>
<p>The next property is the size property, which controls the size of the font.  Now this is slightly different in that it calls the create_font() function rather then the update_surface() function that the text and the colour property did. </p>
<p>The reason for this is that the size property is used in the creation of the actual font object that is used to update the surface which is eventually drawn to the screen.  As with the update_surface() function I will explain the create_font() function later.  Properties that call create_font() do not have to call update_surface() because create_font() calls update_surface().</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Font Filename
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_font_filename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_font_filename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">font_filename</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-code"> != </span><span class="hl-identifier">font_filename</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-default"> = </span><span class="hl-identifier">font_filename
        self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">font_filename</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_font_filename</span><span class="hl-code">, </span><span class="hl-identifier">__set_font_filename</span><span class="hl-brackets">)</span></pre></div></div>
<p>Then we have the font_filename property that represents the full path to the font file.  So if that changes we need to recreate the font in order to display the text using the correct font.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Highlight
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_highlight</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_highlight</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">not</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-code"> == </span><span class="hl-identifier">highlight</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-comment">#Save the bold_rect
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect
        self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-default"> = </span><span class="hl-identifier">highlight
        </span><span class="hl-comment">#update the cursor
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">()
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> += </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> -= </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase
        if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight_increase</span><span class="hl-code"> == </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()
</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_highlight</span><span class="hl-code">, </span><span class="hl-identifier">__set_highlight</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next we have the highlight property, the highlight property is a boolean property that controls whether or not the TextWidget should display &#8220;highlighted&#8221; or not.  When a TextWidget is highlighted the font will be displayed in bold, have its size increased by a specific amount, and (if enabled) the hand cursor will be displayed.</p>
<p>So now since the __get_highlight() function is the same as all of the others, I&#8217;ll just explain the __set_highlight() function.</p>
<p>First we check to see that the new value is different then the old value.  We do this so that we don&#8217;t waste time with useless font creations or extra draws.  </p>
<p>Then we check to see if the current state of the TextWidget is highlighted, because if it is, we know that it is about to go back to normal (because of the first if.)  If that is the case we save the current rect as bold_rect so that the next time we draw we will want bold_rect to be drawn so that all of the previous highlighted text is overwritten.</p>
<p>Then we set the internal highlight value and call the update_cursor() function which will decide whether or not the cursor should be a hand or the default arrow.  </p>
<p>Then we set the size of the font depending on whether or not the highlight state has been turned on.  If it is we increase the size, and if it is not we decrease the size back down to normal.  </p>
<p>Since increasing or decreasing the size will call create_font() we only need to call create_font() if self.highlight_increase is equal to zero, since in that case the value of the size property will not change and the font will not be created. </p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Show Highlight Cursor
</span><span class="hl-reserved">def </span><span class="hl-identifier">__get_highlight_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor
</span><span class="hl-reserved">def </span><span class="hl-identifier">__set_highlight_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-code"> != </span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-default"> = </span><span class="hl-identifier">highlight_cursor
        self</span><span class="hl-default">.</span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">()
</span><span class="hl-identifier">highlight_cursor</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_highlight_cursor</span><span class="hl-code">, </span><span class="hl-identifier">__set_highlight_cursor</span><span class="hl-brackets">)</span></pre></div></div>
<p>Lastly we have the highlight_cursor property, which is a boolean property that  controls whether or not the highlight (hand) cursor should be displayed.  If you have made it this far and have understood the rest of the properties then understanding this property shouldn&#8217;t be too difficult.  Basically it simply checks to see if we should update the property, and if so it updates it and then calls update_cursor() just in case we need the cursor to update right now.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">colour</span><span class="hl-code">=</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">size</span><span class="hl-code">=</span><span class="hl-number">32</span><span class="hl-code">
             , </span><span class="hl-identifier">highlight_increase</span><span class="hl-code"> = </span><span class="hl-number">20</span><span class="hl-code">, </span><span class="hl-identifier">font_filename</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-code">
             , </span><span class="hl-identifier">show_highlight_cursor</span><span class="hl-code"> = </span><span class="hl-reserved">True</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize the TextWidget
    @param text = &quot;&quot; - string - The text for the text widget
    @param colour = (0,0,0) - The colour of the text
    @param size = 32 - number - The size of the text
    @param highlight_increate - number - How large do we want the
    text to grow when it is highlighted?
    @param font_filename = None - string the patht to the font file
    to use, None to use the default pygame font.
    @param show_highlight_cursor = True - boolean - Whether or not to change
    the cursor when the text is highlighted.  The cursor will turn into
    a hand if this is true.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-comment">#inits
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_increase</span><span class="hl-default"> = </span><span class="hl-identifier">highlight_increase
    self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    
    </span><span class="hl-comment">#property inits
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_text</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_colour</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_size</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font_filename</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_highlight_cursor</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
    
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">text
    self</span><span class="hl-default">.</span><span class="hl-identifier">colour</span><span class="hl-default"> = </span><span class="hl-identifier">colour
    self</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-identifier">size
    self</span><span class="hl-default">.</span><span class="hl-identifier">font_filename</span><span class="hl-default"> = </span><span class="hl-identifier">font_filename
    self</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">highlight_cursor</span><span class="hl-default"> = </span><span class="hl-identifier">show_highlight_cursor
    
    self</span><span class="hl-default">.</span><span class="hl-identifier">create_font</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now we actually start using the class the first thing we do is code the __init__() function in which we initialize all of our data members and properties, and then create the font at the end.  This may result in the font being create twice sometimes but it will only happen once when the Widget is created, and it makes sure that the font is always created.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">update_cursor</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight_cursor</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">mouse</span><span class="hl-default">.</span><span class="hl-identifier">set_cursor</span><span class="hl-brackets">(</span><span class="hl-code">*</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__hand</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">mouse</span><span class="hl-default">.</span><span class="hl-identifier">set_cursor</span><span class="hl-brackets">(</span><span class="hl-code">*</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">cursors</span><span class="hl-code">.</span><span class="hl-identifier">arrow</span><span class="hl-brackets">)</span></pre></div></div>
<p>Here is the update_cursor() function, it&#8217;s pretty straight forward.  First we check whether or not we are supposed to change the cursor at all.  If we are then we check to see if we are highlighted or not.  If we are highlighted then we use the hand cursor that we created above, and if we are not highlighted we use the built-in pygame arrow cursor.</p>
<h2>Drawing and Fonts</h2>
<p>Now we finally get to drawing and the font creation that we talked about earlier.  The first thing to do is to create our font:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_font</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create the internal font, using the current settings
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">size</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">Font</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">font_filename</span><span class="hl-code">
                                 , </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">size</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">update_surface</span><span class="hl-brackets">()</span></pre></div></div>
<p>As you can see this function really is pretty simple, all we need to make sure that we have is a size for the font.  Then we create the font using <a href="http://www.pygame.org/docs/ref/font.html#pygame.font.Font">pygame.font.Font()</a>  We don&#8217;t care if self.font_filename is None since if it is None, then the default font will be loaded. </p>
<p>After the font has been created we call update_surface():</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">update_surface</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Update the current surface, basically render the
    text using the current settings.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__m_font</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default">.</span><span class="hl-identifier">set_bold</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">highlight</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__m_font</span><span class="hl-default">.</span><span class="hl-identifier">render</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">
                                        , </span><span class="hl-reserved">True</span><span class="hl-code">
                                        , </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">colour</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-comment"># Used the current rects center point
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">(</span><span class="hl-identifier">center</span><span class="hl-code">=</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">center</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span></pre></div></div>
<p>In update_surfacte() we first make sure that our font (__m_font) exists, since if it does not then there is no point in creating any surface.  Then we set the font&#8217;s bold setting <a href="http://www.pygame.org/docs/ref/font.html#Font.set_bold">Font.set_bold()</a> function and controlled by the highlight property.</p>
<p>Then we render the font onto a <a href="http://www.pygame.org/docs/ref/surface.html#pygame.Surface">pygame.surface</a> using the <a href="http://www.pygame.org/docs/ref/font.html#Font.render">Font.render()</a> function and our current text and colour.  We also make sure that the font is anti-aliased by passing True as the second parameter.</p>
<p>Then we set self.Dirty to True to make sure that the next time through the draw loop the new surface gets displayed.  </p>
<p>The last thing we do in the function is move our text into the correct location.  If self.rect has been specified then we move the image into that position and set our rect, otherwise we initialize self.rect to be be surfaces rectangle.  </p>
<p>self.rect must eventually be move into some position because <a href="http://www.pygame.org/docs/ref/surface.html#Surface.get_rect">Surface.get_rect()</a> always returns a rectangle that starts at 0,0.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">screen</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw yourself text widget
    @param screen - pygame.Surface - The surface that we will draw to
    @returns - pygame.rect - If drawing has occurred this is the 
    rect that we drew to.  None if no drawing has occurred.</span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-reserved">None
    </span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">image</span><span class="hl-brackets">)  </span><span class="hl-identifier">and  </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">) </span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">dirty</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">bold_rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">We may need to overwrite the bold text size
            This gets rid of leftover text when moving from 
            bold text to non-bold text.
            </span><span class="hl-quotes">&quot;&quot;&quot;
            </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">Rect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">bold_rect</span><span class="hl-brackets">)
            </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set to None, since we only need to do this
            once.</span><span class="hl-quotes">&quot;&quot;&quot;
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">bold_rect</span><span class="hl-default"> = </span><span class="hl-reserved">None
        else</span><span class="hl-default">:
            </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">rect
        </span><span class="hl-comment">#Draw the text
        </span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">image</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Dirty no more
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">False

    return </span><span class="hl-identifier">rect_return</span></pre></div></div>
<p>Finally we get to the draw code, and thankfully it&#8217;s pretty simple.  The draw() function take a <a href="http://www.pygame.org/docs/ref/surface.html">pygame.Surface</a> as the only parameter, this is the surface that we will be drawing to, probably the main surface in your game or application.  The draw function will also return a  <a href="http://www.pygame.org/docs/ref/rect.html">pygame.Rect</a> object (or None) which represents the area of the surface that needs to be updated (or not).</p>
<p>The first thing we do in the function is make sure that we actually have something to draw.  We check our rectangle (self.tect) and our surface (self.image) to make sure that everything has been initialized, and then we check self.dirty to see if we <em>should</em> draw anything. </p>
<p>Then we check to see if self.bold_rect is valid, if it is we return it as the rectangle to update and invalidate the bold_rect, since it only needed once, when moving from highlighted to non-highlighted). If self.bold_rect is not valid then we will return self.rect as the rectangle to update.</p>
<p>Then we <a href="http://www.pygame.org/docs/ref/surface.html#Surface.blit">blit</a> our text to the screen (which is stored in self.image as a pygame.Surface object) and set self.dirty to False so that we do not needlessly draw in the future.</p>
<h2>Events</h2>
<p>If you remember way back at the beginning of this tutorial we create a define for a future event that would be fired when the TextWidget was clicked on:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals</span><span class="hl-default">.</span><span class="hl-identifier">USEREVENT</span><span class="hl-default"> + </span><span class="hl-number">1</span></pre></div></div>
<p>Now is where we use it and let the main class know when a TextWidget has been clicked.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires.
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Check for collision
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">True</span></pre></div></div>
<p>First we have the on_mouse_button_down() function, this should be called by your main application during the event loop.  If you come across a MOUSEBUTTONDOWN event, then you should pass it to all of your TextWidget objects, or at least the TextWidgets that you want to be interactive.</p>
<p>All this function does is check to see if the mouse button down event occurred within the TextWidgets rect, if it did, self.Tracking is set to True to let the TextWidget know that it is “tracking” or listening for the MOUSEBUTTONUP event to complete the click.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires.
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Check for collision
    </span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">tracking</span><span class="hl-brackets">) </span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">rect</span><span class="hl-code">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)))</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-comment">#Not Tracking anymore
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">tracking</span><span class="hl-default"> = </span><span class="hl-reserved">False</span></pre></div></div>
<p>Next we have the on_mouse_button_up function which called by your main application for all of your interactive TextWidget objects when the MOUSEBUTTONDOWN event is found.  </p>
<p>This function is very simple, it first checks to see if we are currently tracking, if we are then we check to see if the event has occurred within the TextWidget&#8217;s rect.  If it has we call self.one_mouse_click() and pass it the event.</p>
<p>Then we set self.tracking to False, since whatever happened we are no longer tracking.  Now if you don&#8217;t fully understand what the self.tracking boolean does, it simply makes sure that the TextWidget behaves like a standard button, which means that it only registers MOUSEBUTTONUP events as a &#8220;click&#8221; if the MOUSEBUTTONDOWN also occurred within the buttons rectangle.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_mouse_click</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called by the main application when the
    MOUSEBUTTONDOWN event fires, and the text widget
    has been clicked on.  You can either let
    this post the event (default) or you can override this
    function call in your app.
    ie. myTextWidget.on_mouse_click = my_click_handler
    @param event - Pygame Event object
    MOUSEBUTTONDOWN  pos, button
    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-comment">#Create the TEXT_WIDGET_CLICK event
    </span><span class="hl-identifier">event_attrib</span><span class="hl-default"> = {}
    </span><span class="hl-identifier">event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">button</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">button
    event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">pos</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">pos
    event_attrib</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">text_widget</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">self
    e</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">Event</span><span class="hl-brackets">(</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-code">, </span><span class="hl-identifier">event_attrib</span><span class="hl-brackets">)
    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">)</span></pre></div></div>
<p>Finally in our event handling we have the on_mouse_click() function.  By default this function will <a href="http://www.pygame.org/docs/ref/event.html#pygame.event.post">post</a> a TEXT_WIDGET_CLICK event to the PyGame event queue which you can handle in whichever manner you like.</p>
<p>The event has the following attributes:</p>
<ul>
<li>button &#8211; The button of the mouse that was used for the click.  This is the same as the MOUSEBUTTONUP event&#8217;s button attribute.</li>
<li>pos (x,y) &#8211; The position of the mouse cursor when the click occurred.  The is the same as the MOUSEBUTTONUP event&#8217;s pos attribute.</li>
<li>text_widget &#8211; The TextWidget object that was clicked on, so you know how to handle the event.</li>
</ul>
<p>That is the default way that the on_mouse_click() function functions, in general it is probably easier to override the on_mouse_click() function in all of the TextWidget instances that you want to be interactive.</p>
<p>As an example, in your main application you might use the following for an Exit TextWidget:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked</span></pre></div></div>
<h2>Using the TextWidget</h2>
<p>In order to make it easy to see how to use the TextWidget object (if it is not already) I whipped up a quick sample application, the short flash capture is to show you what it looks like without having to run it:</p>
<p>
<embed src="http://www.learningpython.com/flash/textwidget.swf" width="320" height="240" play="true" loop="True" quality="low" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"><br />
</embed>
</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">os</span><span class="hl-default">, </span><span class="hl-identifier">sys
</span><span class="hl-reserved">import </span><span class="hl-identifier">pygame
</span><span class="hl-reserved">from </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">locals </span><span class="hl-reserved">import</span><span class="hl-default"> *

</span><span class="hl-reserved">import </span><span class="hl-identifier">TextWidget

</span><span class="hl-reserved">class </span><span class="hl-identifier">PyGameText</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">An example class used to illustrate possible ways to work
    with the TextWidget text in a pygame game.
    </span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">width</span><span class="hl-code">=</span><span class="hl-number">640</span><span class="hl-code">, </span><span class="hl-identifier">height</span><span class="hl-code">=</span><span class="hl-number">480</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize
        @param width=640 - The width of the pygame window
        @param height=480 - The height of the pygame window.
        </span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">init</span><span class="hl-brackets">()
        </span><span class="hl-comment">#create the screen
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">set_mode</span><span class="hl-brackets">((</span><span class="hl-identifier">width</span><span class="hl-code">, </span><span class="hl-identifier">height</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-brackets">) 
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">Surface</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-code">.</span><span class="hl-identifier">get_size</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-identifier">SWSURFACE</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">convert</span><span class="hl-brackets">()
        </span><span class="hl-identifier">image</span><span class="hl-default">, </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">load_image</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">background.png</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">image</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">image</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-comment">#Just fill with a solid colour
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">background</span><span class="hl-default">.</span><span class="hl-identifier">fill</span><span class="hl-brackets">((</span><span class="hl-number">124</span><span class="hl-code">,</span><span class="hl-number">124</span><span class="hl-code">,</span><span class="hl-number">124</span><span class="hl-brackets">))
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">background</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
        
    </span><span class="hl-reserved">def </span><span class="hl-identifier">main_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">The main Python loop</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">time</span><span class="hl-default">.</span><span class="hl-identifier">Clock</span><span class="hl-brackets">()
        
        </span><span class="hl-comment"># Text Widget list
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default"> = </span><span class="hl-brackets">[]
        </span><span class="hl-comment">#Create our Text WIdgets
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">New Game</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-brackets">))
        </span><span class="hl-comment">#make this the biggest text
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-number">96
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-number">0</span><span class="hl-default">;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">new_game_text</span><span class="hl-brackets">)
        
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">High Scores</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">high_score_text</span><span class="hl-brackets">)
        
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Website</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">website_text</span><span class="hl-brackets">)
        
        </span><span class="hl-comment"># Different font for the last one, and let's make it increase
        # more
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Exit</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">
                                , </span><span class="hl-number">64</span><span class="hl-code">, </span><span class="hl-number">40</span><span class="hl-code">
                                , </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-code">.</span><span class="hl-identifier">match_font</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sans</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-reserved">False</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">))
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
        self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked
        self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">exit_text</span><span class="hl-brackets">)
           
        </span><span class="hl-reserved">while </span><span class="hl-number">1</span><span class="hl-default">: 
            </span><span class="hl-comment">#Tick of the timer
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default">.</span><span class="hl-identifier">tick</span><span class="hl-brackets">()
            
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">event_loop</span><span class="hl-brackets">()
            
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
                
    </span><span class="hl-reserved">def </span><span class="hl-identifier">event_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Perform the event loop.</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-reserved">for </span><span class="hl-identifier">event </span><span class="hl-reserved">in </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">get</span><span class="hl-brackets">()</span><span class="hl-default">:
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">QUIT</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
                </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">ACTIVEEVENT</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">gain</span><span class="hl-code"> == </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-default">:
                    </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                        </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
                    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
                </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">state</span><span class="hl-code"> ==</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-default">: 
                    </span><span class="hl-comment">#We are hidden so wait for the next event
                    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">wait</span><span class="hl-brackets">())             
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEMOTION</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONDOWN</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONUP</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
            </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget             
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw everything</span><span class="hl-quotes">&quot;&quot;&quot;        
        </span><span class="hl-identifier">rects</span><span class="hl-default"> = </span><span class="hl-brackets">[]
        </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">timer_update</span><span class="hl-brackets">())
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-brackets">)
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">(</span><span class="hl-identifier">rects</span><span class="hl-brackets">)        
        
    </span><span class="hl-reserved">def </span><span class="hl-identifier">timer_update</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Update the Timer
        returns - pygame.rect - The rect that the timer
        needs to be redrawn, or None on error</span><span class="hl-quotes">&quot;&quot;&quot;
        
        </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-reserved">None
        
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-brackets">)</span><span class="hl-default">:     
            </span><span class="hl-identifier">timer_string</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">%.2f</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">timer</span><span class="hl-default">.</span><span class="hl-identifier">get_fps</span><span class="hl-brackets">()
            </span><span class="hl-comment">#basic font
            </span><span class="hl-identifier">font</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">Font</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-number">36</span><span class="hl-brackets">)
            </span><span class="hl-identifier">message</span><span class="hl-default"> = </span><span class="hl-identifier">font</span><span class="hl-default">.</span><span class="hl-identifier">render</span><span class="hl-brackets">(</span><span class="hl-identifier">timer_string</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">147</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-code">, </span><span class="hl-number">16</span><span class="hl-brackets">))
            </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">message</span><span class="hl-brackets">)</span><span class="hl-default">:
                </span><span class="hl-identifier">rect_return</span><span class="hl-default"> = </span><span class="hl-identifier">message</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">(</span><span class="hl-identifier">left</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-brackets">)
                </span><span class="hl-identifier">rect_return</span><span class="hl-default">.</span><span class="hl-identifier">width</span><span class="hl-default"> += </span><span class="hl-number">25
                </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">background</span><span class="hl-code">, </span><span class="hl-identifier">rect_return</span><span class="hl-brackets">)
                </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">blit</span><span class="hl-brackets">(</span><span class="hl-identifier">message</span><span class="hl-code">, </span><span class="hl-identifier">rect_return</span><span class="hl-brackets">) 
        
        </span><span class="hl-reserved">return </span><span class="hl-identifier">rect_return
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">load_image</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">name</span><span class="hl-code">, </span><span class="hl-identifier">colorkey</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">full_path</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">realpath</span><span class="hl-brackets">(</span><span class="hl-identifier">os</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-code">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]))
        </span><span class="hl-identifier">full_path</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">full_path</span><span class="hl-code">, </span><span class="hl-identifier">name</span><span class="hl-brackets">)
        </span><span class="hl-reserved">try</span><span class="hl-default">:
            </span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">load</span><span class="hl-brackets">(</span><span class="hl-identifier">full_path</span><span class="hl-brackets">)
        </span><span class="hl-reserved">except </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">error</span><span class="hl-default">, </span><span class="hl-identifier">message</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">'</span><span class="hl-string">Cannot load image:</span><span class="hl-quotes">'</span><span class="hl-default">, </span><span class="hl-identifier">full_path
            </span><span class="hl-reserved">return None</span><span class="hl-default">, </span><span class="hl-reserved">None
        </span><span class="hl-identifier">image</span><span class="hl-default"> = </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">convert</span><span class="hl-brackets">()
        </span><span class="hl-reserved">if </span><span class="hl-identifier">colorkey </span><span class="hl-reserved">is not None</span><span class="hl-default">:
            </span><span class="hl-reserved">if </span><span class="hl-identifier">colorkey </span><span class="hl-reserved">is</span><span class="hl-default"> -</span><span class="hl-number">1</span><span class="hl-default">:
                </span><span class="hl-identifier">colorkey</span><span class="hl-default"> = </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_at</span><span class="hl-brackets">((</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))
            </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">set_colorkey</span><span class="hl-brackets">(</span><span class="hl-identifier">colorkey</span><span class="hl-code">, </span><span class="hl-identifier">RLEACCEL</span><span class="hl-brackets">)
        </span><span class="hl-reserved">return </span><span class="hl-identifier">image</span><span class="hl-default">, </span><span class="hl-identifier">image</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">on_exit_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
        </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">PyGameText</span><span class="hl-brackets">()
    </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">main_loop</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now most of the code isn&#8217;t that exciting and is a pretty basic example of a short PyGame application so I won&#8217;t explain every line of this code.  I will highlight three portions:</p>
<h3>Text Widget Creation</h3>
<p>Here is how I created the four TextWidgets in the example application, each is slightly different so you might want to look at each and try to understand what it is doing:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># Text Widget list
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default"> = </span><span class="hl-brackets">[]
</span><span class="hl-comment">#Create our Text WIdgets
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">New Game</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-brackets">))
</span><span class="hl-comment">#make this the biggest text
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">size</span><span class="hl-default"> = </span><span class="hl-number">96
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-number">0</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">new_game_text</span><span class="hl-brackets">)

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">High Scores</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">new_game_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">high_score_text</span><span class="hl-brackets">)

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Website</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-number">64</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">high_score_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">website_text</span><span class="hl-brackets">)

</span><span class="hl-comment"># Different font for the last one, and let's make it increase
# more
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default"> = </span><span class="hl-identifier">TextWidget</span><span class="hl-default">.</span><span class="hl-identifier">TextWidget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Exit</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-number">255</span><span class="hl-code">,</span><span class="hl-number">255</span><span class="hl-brackets">)</span><span class="hl-code">
                        , </span><span class="hl-number">64</span><span class="hl-code">, </span><span class="hl-number">40</span><span class="hl-code">
                        , </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">font</span><span class="hl-code">.</span><span class="hl-identifier">match_font</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sans</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-reserved">False</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">))
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">center</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">screen</span><span class="hl-default">.</span><span class="hl-identifier">get_rect</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">center
self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">top</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">website_text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">bottom</span><span class="hl-default"> + </span><span class="hl-number">30</span><span class="hl-default">;
</span><span class="hl-comment"># Override the on_mouse_click function
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">exit_text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_click</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_exit_clicked
self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">exit_text</span><span class="hl-brackets">)</span></pre></div></div>
<p>In general this code is pretty simple, it mostly involves creating our TextWidget objects, settings some of their properties and then adding them to a list.  It really should be pretty self explanatory how this code works, one thing that I will point out is how the in the exit_text TextWidget the pygame.font.match_font() function is used to get the path to the font, and the on_mouse_click() function is overridden.</p>
<h3>The Event Loop</h3>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">event_loop</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Perform the event loop.</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">for </span><span class="hl-identifier">event </span><span class="hl-reserved">in </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">get</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">QUIT</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-brackets">()
        </span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">()
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">ACTIVEEVENT</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">gain</span><span class="hl-code"> == </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
                </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">dirty</span><span class="hl-default"> = </span><span class="hl-reserved">True
            </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">()
        </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">state</span><span class="hl-code"> ==</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-default">: 
            </span><span class="hl-comment">#We are hidden so wait for the next event
            </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">post</span><span class="hl-brackets">(</span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">wait</span><span class="hl-brackets">())             
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEMOTION</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">highlight</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">rect</span><span class="hl-default">.</span><span class="hl-identifier">collidepoint</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">pos</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONDOWN</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_down</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">pygame</span><span class="hl-code">.</span><span class="hl-identifier">MOUSEBUTTONUP</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
            </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">on_mouse_button_up</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-brackets">)
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget</span></pre></div></div>
<p>The first thing you should notice is that we respond to the ACTIVEEVENT, we do this so that when the PyGame window gets focus back (after loosing it) we redraw all of the text widgets.  We force the TextWidgets to redraw by setting the dirty member to True.</p>
<p>Next we set the TextWidget.highlight property by checking for a collision with each TextWidget rect when we get the MOUSEMOTION event.</p>
<p>If you want your TextWidgets to be responsive to a click whenever you get a MOUSEBUTTONDOWN or MOUSEBUTTONUP event you can simply pass it forward to the on_mouse_button_down() and on_mouse_button_up() functions in each widget, the TextWidget will take care of the rest of the processing.</p>
<p>The example also shows how to handle the TEXT_WIDGIT_CLICK event:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">type</span><span class="hl-code"> == </span><span class="hl-identifier">TextWidget</span><span class="hl-code">.</span><span class="hl-identifier">TEXT_WIDGET_CLICK</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">text_widget</span></pre></div></div>
<p>In the example I simply print out the TextWidget, but you could do whatever you wanted to.</p>
<h3>The Draw Loop</h3>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Draw everything</span><span class="hl-quotes">&quot;&quot;&quot;        
    </span><span class="hl-identifier">rects</span><span class="hl-default"> = </span><span class="hl-brackets">[]
    </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">timer_update</span><span class="hl-brackets">())
    </span><span class="hl-reserved">for </span><span class="hl-identifier">text </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_widgets</span><span class="hl-default">:
        </span><span class="hl-identifier">rect</span><span class="hl-default"> = </span><span class="hl-identifier">text</span><span class="hl-default">.</span><span class="hl-identifier">draw</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">screen</span><span class="hl-brackets">)
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">rects</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">rect</span><span class="hl-brackets">)
    </span><span class="hl-identifier">pygame</span><span class="hl-default">.</span><span class="hl-identifier">display</span><span class="hl-default">.</span><span class="hl-identifier">update</span><span class="hl-brackets">(</span><span class="hl-identifier">rects</span><span class="hl-brackets">)</span></pre></div></div>
<p>The draw loop is actually pretty simple.  I use a list to keep track of rectangles that I want to update at the end of the draw using <a href="http://www.pygame.org/docs/ref/display.html#pygame.display.update">pygame.display.update()</a> function.</p>
<p>In order to draw the TextWidget&#8217;s I simply loop through the list of them and call their draw() function.  If the draw() function returns a rectangle, then I know that the TextWdiget has drawn so I add it to the list of rectangles that need to be updated.  </p>
<p>If None is returned then I know that the TextWidget has not drawn and that it does not need to be drawn. </p>
<h2>Conclusion</h2>
<p>The full source and necessary files for this tutorial can be downloaded <a href="http://www.learningpython.com/sources/TextWidget.tar.gz">here</a>.</p>
<p>So that&#8217;s it for this tutorial, as I said early on I&#8217;m not saying that this is the best or only way to work with text, I&#8217;m simply presenting this as a possible way to work with text, or as an example that might help get you started with your own text processing.</p>
<p>If you have any suggestions, problems, or notice anything that is incorrect, as always, add a comment! </p>
<p>Feel free to use this in whatever manner you want (it&#8217;s licensed under the LGPL), but if you do end up using it, I would appreciate it if you sent me an email and let me know.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/&title=TextWidget - A simple text class for PyGame&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>WordPy 0.2 &#8211; Using XML to Save and Load Data</title>
		<link>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/</link>
		<comments>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 02:22:52 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[WordPy]]></category>
		<category><![CDATA[glade]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=41</guid>
		<description><![CDATA[
			
				
			
		
All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file.  Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file.  Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods and this method was chosen for its simplicity.</p>
<p>If you are unfamiliar with the <a href="http://www.learningpython.com/2006/08/19/wordpress-python-library/">first WordPy tutorial</a> you should probably read it fist in order to have a better understanding of some of what happens in this tutorial. </p>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<h2>The GUI</h2>
<p>The first thing we need to-do is open up the wordpy glade project and make some changes:</p>
<ol>
<li>We&#8217;ll start off by adding another item to our VBox in Glade.  You can do this by holding down shift and clicking on the WordPy window until you see the GTKVBox come up in the properties window.  Then simply change it&#8217;s size value from 4 to 5.</li>
<li>In the empty space add a menu bar.  Then on the Packing tab of the menu bar&#8217;s properties set the position to be zero, so that the menu is at the top of the window.</li>
<li>Then edit the menu so that only the  File, Edit, and Help menu&#8217;s remain.</li>
<li>Add handlers to each of the files menu items: on_file_new, on_file_open, on_file_save, on_file_save_as</li>
</ol>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_02/wordpy_02_01.png" alt="GLADE Window PyWine" border="0" /></p>
<h2>The Code</h2>
<p>That&#8217;s it for editing the GUI, now we have to go and edit the code.  The first step is to connect all of the menu events with our code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_wndMain_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBold_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnItalic_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnLink_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBlockQuote_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnDel_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnIns_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnImage_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnUnorderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnOrderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnListItem_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnCode_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnMore_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnSettings_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnpost_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_new</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_open</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_open</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save_as</span><span class="hl-quotes">&quot;</span><span class="hl-default">: </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save_as</span><span class="hl-default">}
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">signal_autoconnect</span><span class="hl-brackets">(</span><span class="hl-identifier">dic</span><span class="hl-brackets">)</span></pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">. </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p><span id="more-41"></span></p>
<p>Now when we save and load the post we will need to use the same xml tags, so instead of typing them twice (or in case we want to change them) I decided to save them as a dictionary in the WordPy class:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> = </span><span class="hl-number">0
</span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> = </span><span class="hl-number">1
</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> = </span><span class="hl-number">2
</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> = </span><span class="hl-number">3
</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> = </span><span class="hl-number">4
</span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> = </span><span class="hl-number">5
</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> = </span><span class="hl-number">6
</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> = </span><span class="hl-number">7

</span><span class="hl-reserved">class </span><span class="hl-identifier">WordPy</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the Wordpy application.  It is a simple PyGTK
	application that interacts with the WorPress Python library.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">_xml_tags</span><span class="hl-default"> = {
			</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Post</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Title</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Text</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">URL</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Settings</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Username</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">password</span><span class="hl-quotes">&quot;</span><span class="hl-default">
	}</span></pre></div></div>
<p>Now when we save and load we can get the username xml tag like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>And if someone wants to import WordPy into their own Python project, they could get at the tags (if they didn&#8217;t have a WordPy object instantiated) like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">WordPy</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>We also need to add a new element in the __init__() function:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None</span></pre></div></div>
<p>This will be the full path to the xml file that is represents the current post, it starts off as None, since when we first start WordPy the blank post is not associated with any xml file.</p>
<p>We will also need to do some file browsing for the save, open, and save as events so we&#8217;ll borrow the file_browse() function from the <a href="http://www.learningpython.com/2006/09/02/extending-our-pygtk-application/">Extending our PyGTK application</a> tutorial (to learn more about the function and how it works please read the tutorial):</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># Borrowed from the PyWine project
</span><span class="hl-reserved">def </span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">dialog_action</span><span class="hl-code">, </span><span class="hl-identifier">file_name</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function is used to browse for a pyWine file.
	It can be either a save or open dialog depending on
	what dialog_action is.
	The path to the file will be returned if the user
	selects one, however a blank string will be returned
	if they cancel or do not select one.
	dialog_action - The open or save mode for the dialog either
	gtk.FILE_CHOOSER_ACTION_OPEN, gtk.FILE_CHOOSER_ACTION_SAVE
	@param file_name - Default name when doing a save
	@returns - File Name, or None on cancel.
	</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_OPEN</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Open Post</span><span class="hl-quotes">&quot;
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_SAVE</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Save Post</span><span class="hl-quotes">&quot;

	</span><span class="hl-identifier">file_dialog</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileChooserDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">=</span><span class="hl-identifier">dlg_title</span><span class="hl-code">
		, </span><span class="hl-identifier">action</span><span class="hl-code">=</span><span class="hl-identifier">dialog_action</span><span class="hl-code">
		, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-identifier">dialog_buttons</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">set the filename if we are saving</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">set_current_name</span><span class="hl-brackets">(</span><span class="hl-identifier">file_name</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the pywine filter</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy Post</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.</span><span class="hl-quotes">&quot;</span><span class="hl-code"> + </span><span class="hl-identifier">FILE_EXT</span><span class="hl-brackets">)
	</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the 'all files' filter</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">All files</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)

	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Init the return value</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-reserved">None
	if </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span><span class="hl-default"> == </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-default">:
		</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">get_filename</span><span class="hl-brackets">()
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">result</span><span class="hl-default">, </span><span class="hl-identifier">extension</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">splitext</span><span class="hl-brackets">(</span><span class="hl-identifier">result</span><span class="hl-brackets">)
			</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">result</span><span class="hl-default"> + </span><span class="hl-quotes">&quot;</span><span class="hl-string">.</span><span class="hl-quotes">&quot;</span><span class="hl-default"> + </span><span class="hl-identifier">FILE_EXT
	file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()

	</span><span class="hl-reserved">return </span><span class="hl-identifier">result</span></pre></div></div>
<p>Note that this function is somewhat different then the original in that it returns None if the users cancels the operation rather then returning a blank string.</p>
<p>I set FILE_EXT to &#8220;wpx&#8221;, which stands for WordPy xml, at the beginning of the WordPy.py file near the top:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">FILE_EXT</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">wpx</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Another helper function that I added is the set_post_text function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Simple Helper function that sets the text
	in the text View.
	@param text - The text that will be put into
	the text view.
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#select all of the text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)
	</span><span class="hl-comment">#insert over the selection i.e. replace all the text
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">)
	</span><span class="hl-comment">#put the selection at the end.
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">end</span><span class="hl-brackets">)</span></pre></div></div>
<p>It&#8217;s a simple helper function that sets the post text.  It does this by selecting all of the text in the gtk.TextView and then calls the insert_text() function (detailed in the  previous tutorial) which will overwrite what is selected in the gtk.TextView (in this case everything) with the text that it is passed.  After that we simply move the cursor caret to the end of the text.</p>
<h3>Saving the post</h3>
<p>Now that we have all of the base code in place we can start work on actually saving our file to xml, to do that we will use the <a href="http://docs.python.org/lib/module-xml.dom.minidom.html">xml.dom.minidom</a> module.  The reason that I decided to use the xml.dom.minidom object as opposed to the xml.dom object is because the:</p>
<blockquote><p>xml.dom.minidom is a light-weight implementation of the Document Object Model interface. It is intended to be simpler than the full DOM and also significantly smaller.</p></blockquote>
<p>This is perfect for us since we for saving and loading we do not need to perform any exceedingly difficult xml tasks.</p>
<p>The first function we are going to implement is the on_file_save() function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function saves the current post as an XML file</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment"># Let the user browse for the save location and name
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> == </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-comment">#Allright it all worked! Set the Title
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>This function is pretty simple since it relies on many other functions, this was done so that a lot of the code could be re-used by the on_file_save_as() function. The first thing we do is check to see if self.xml_name has been set, if it hasn&#8217;t we pop up a save dialog and let the user select the location where their file will be saved.  Then if they chose a filename rather then cancelling we will actually start saving our data to xml.</p>
<p>The two main functions we use to accomplish this are xml_save_to_file() and set_window_title_file().  set_window_title_file() is a very simple function that sets the main windows title based upon a file path:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the windows title, take it from xml_file.
	@param xml_file - string - The xml file name that we will
	base the window title off of
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - %s</span><span class="hl-quotes">&quot;</span><span class="hl-code">
			% </span><span class="hl-brackets">(</span><span class="hl-identifier">os</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-code">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - Untitled</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The more complicated function is the xml_save_to_file() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current post to xml_file
	@param xml_file - string - path to file that
	we will save the xml to.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Get the available DOM Implementation
	</span><span class="hl-identifier">impl</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">getDOMImplementation</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Create the document, with wordpy as to base node
	</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">impl</span><span class="hl-default">.</span><span class="hl-identifier">createDocument</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-reserved">None</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the post settings into the xml
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the Blog settings into the XML
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now actually try to save the file
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">save_file</span><span class="hl-default"> = </span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">w</span><span class="hl-quotes">'</span><span class="hl-brackets">)
		</span><span class="hl-comment">#write the xml document to disc
		</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">writexml</span><span class="hl-brackets">(</span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">save_file</span><span class="hl-default">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error saving post(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-comment">#Allright it all worked! Set the return value
		</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">True

	return </span><span class="hl-identifier">success</span></pre></div></div>
<p>The code is a bit complicated so I will take a little bit of time trying to explain each part in it.  The first thing that we do (after initializing the return value) is call minidom.GetDomImplementation() to get a suitable DOM implementation.  You can read more about the Document Object Model in the python documentation <a href="http://docs.python.org/lib/module-xml.dom.html">here</a>.  We then use that DOM implementation to create our xml document using self._xml_tags[MAIN_TAG] as the main tag for our xml document.  Basically this creates:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>&lt;WordPy&gt;&lt;/WordPy&gt;</pre></div></div>
<p>Then we call two functions self.xml_save() and self.BlogSettings.xml_save() which are functions that will actually save our data into the xml document.  Then we try to open our self.xml_file and write the xml document into that file using the writexml function:</p>
<blockquote><p><strong>writexml(  	writer[,indent=""[,addindent=""[,newl=""]]])</strong><br />
Write XML to the writer object. The writer should have a write() method which matches that of the file object interface. The indent parameter is the indentation of the current node. The addindent parameter is the incremental indentation to use for subnodes of the current one. The newl parameter specifies the string to use to terminate newlines.</p></blockquote>
<p>After that we simply set the windows title based on self.xml_file so that the user knows which file they are currently working with.</p>
<p>The next function to look at is the WordPy.xml_save() function which actually looks more complicated then it really is:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;post&quot; xml element
	</span><span class="hl-identifier">post_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])  </span><span class="hl-comment"># creates &lt;post&gt;&lt;/post&gt;
	#Title
	</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-identifier">end</span><span class="hl-brackets">)
	</span><span class="hl-comment"># creates &lt;title&gt;&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;title&gt;title text&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-brackets">))
	</span><span class="hl-comment"># creates &lt;text&gt;&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment"># creates &lt;text&gt;text&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Now create &lt;post&gt;&lt;title&gt;title text&lt;/title&gt;&lt;text&gt;text&lt;/text&gt;&lt;/post&gt;
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">title_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">text_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">post_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically it&#8217;s quite simple, we call  xml_document.createElement() to create an xml element (see <a href="http://docs.python.org/lib/dom-document-objects.html">this page</a> for more information on functions available to our Document object.)  Then if we want we create a text node (and xml node that contains a text string) using xml_document.createTextNode() and add that to our newly created xml element.</p>
<p>So the first thing we do is create the post element, and then we create the title and text elements and add those to the post element.  Then we add the post element to the root of our xml document using documentElement which always represents the root element of our xml document.  It&#8217;s really quite simple, hopefully the comments in the code will help to explain each basic step.</p>
<p>The other xml_save function we have is the WordPressBlogSettings.xml_save() function which is very similar to the other xml_save() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;settings&quot; xml element
	</span><span class="hl-identifier">settings_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;url&gt;&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;url&gt;URL&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;username&gt;&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;username&gt;Username&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;password&gt;&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;password&gt;Password&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-brackets">))
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Now create:
	&lt;post&gt;
		&lt;url&gt;URL&lt;/url&gt;
		&lt;username&gt;Username&lt;/username&gt;
		&lt;password&gt;Password&lt;/password&gt;
	&lt;/post&gt;
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">URL_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">username_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">password_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">settings_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>After all this is set and done we end up with an xml file that looks similar to this although not spaced as nicely:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;	http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>Now that you see how we can save a file in response to the File | Save menu command you can probably imagine how we will respond to the File | Save As command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Let the user save the current file to a new location.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Untitled</span><span class="hl-quotes">&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> != </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>You&#8217;ll notice that it&#8217;s very similar to the on_file_save() function except that we always browse for a file and we pass the name of the current file (if it exists) to the file_browse() function so that the use has a starting point for their save as action.</p>
<p>So that&#8217;s it for saving the next step is opening a saved file.</p>
<h3>Opening an save file</h3>
<p>Opening one of our xml files is very similar to saving them except instead of creating the xml document and each node, we need to loop through an existing document and load each node into our specific variables.  The first thing that we need to do is respond to the File | Open menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty standard stuff, we let the user browse for an xml file, and if they don&#8217;t cancel the operation we then load the xml file.  If that is successful we save the path to the xml file and then set the windows title.  Not much happening here as most of the work is done in xml_load_from_file():</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load a post from an xml file
	@param xml_file - string - path to file that
	we will load.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Load the xml_file to a document
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">))
					</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">except</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-reserved">return </span><span class="hl-identifier">success</span></pre></div></div>
<p>In this function we create our xml.minidom.Document object by telling the minidom mdule to parse the xml file that was passed to the function.  If that does not succeed we catch the appropriate exceptions and show our error dialog top the user.  If the parsing the file does succeed we load the post and the blog settings from the XML document. WordPy.xml_load() loads the post from the xml document:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the title, the firstChild in this case is
					the actual title text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;

					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the text, the firstChild in this case is
					the actual text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
			</span><span class="hl-comment">#Break out of the topmost for loop
			</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">title_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">text_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically what we do when loading our values is loop through the all of the child nodes of the root node looking for nodes that match whatever criteria we are looking for.  So in the xml example file:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>The root node or the documentElement item, is the &lt;wordpy&gt; element.  So if we were to loop through its child nodes the first node that we would encounter would be the &lt;post&gt; node and then next node would be the &lt;settings&gt; node.  Then if we looped through he &lt;post&gt; elements children we would encounter the &lt;title&gt; and the &lt;text&gt; node.  The sole child node of either of those two nodes happens to be their actual text.</p>
<p>After explaining that it should be pretty obvious what is happening in the WordPy.xml_load() function.  Basically we loop through all the children of the root node looking for the &lt;post&gt; node.  Once we find it we then loop through all of the  &lt;post&gt; node&#8217;s children looking for the &lt;title&gt; and the &lt;text&gt; node.  When we encounter either the &lt;title&gt; node or the &lt;text&gt; node we get the the nodeValue of the firstChild, if it exists.  The firstChild of either of those two nodes happens to be the actual text node that we want to load.  The nodeValue of the text nodes is their actual text.  If firstChild did not exist it means that a blank string was saved into the text file.</p>
<p>For me the xml metaphoer built up by the xml.dom slightly of falls apart when then actual text is considered another node, but the implementation is simple and works well enough so I shouldn&#8217;t complain. (Plus there is probably a very good reason for this)</p>
<p>We also set boolean values to True to make sure that we know whether or not all of the proper elements were loaded.  This is an optional step as you might not care if everything was loaded properly..</p>
<p>The BlogSettings.xml_load() function does the exact same thing except that it looks for different nodes, as a result I will show it but I won&#8217;t bother explaining it.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the URL</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the username</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the pasword</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
		</span><span class="hl-comment">#Break out of the topmost for loop
		</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">URL_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">username_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">password_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<h3>Starting a new file</h3>
<p>All that&#8217;s left now is to handle the File | New menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>It doesn&#8217;t really do much except blank out the title and text, make it so that there is no xml file, and sets the window title to &#8220;Wordpy – Untitled&#8221; (which is what set_window_title will do when passed None as the xml file.)</p>
<p>Since this is a good way to initialize WordPy I call it in the __init__ function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#initialize to new
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span></pre></div></div>
<h2>The End</h2>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<p>Well that&#8217;s it for this lesson on saving and loading data from an xml file, there are still many more things that need to be done to WordPy, like figuring out what the best way to handle the blog settings are since I&#8217;ve never been happy with the way that they were handled in the previous tutorial.  For example  should they be separate from the post&#8217;s when you save them?  Should there be a list of blog settings?  Should you have to log into your blog first?  I&#8217;m not sure yet but those will be left for another post since this one was simply designed to show one method for saving and loading data from xml files using python.</p>
<p>As always if you have any questions or notice any problems please leave a comment!</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/&title=WordPy 0.2 - Using XML to Save and Load Data&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Creating a GUI in Python using Tkinter</title>
		<link>http://www.learningpython.com/2006/02/08/creating-a-gui-in-python-using-tkinter/</link>
		<comments>http://www.learningpython.com/2006/02/08/creating-a-gui-in-python-using-tkinter/#comments</comments>
		<pubDate>Wed, 08 Feb 2006 05:42:53 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[beginnings]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tkinter]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=11</guid>
		<description><![CDATA[
			
				
			
		
Up until now we&#8217;ve focused on python applications that only run in the command line.  For a lot of tasks this is great, but in order to be really impressive we&#8217;re going to want to create a GUI for some of our python applications.
There are a lot of python GUI toolkits out there, but [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F02%2F08%2Fcreating-a-gui-in-python-using-tkinter%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F02%2F08%2Fcreating-a-gui-in-python-using-tkinter%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Up until now we&#8217;ve focused on python applications that only run in the command line.  For a lot of tasks this is great, but in order to be really impressive we&#8217;re going to want to create a GUI for some of our python applications.</p>
<p>There are a lot of python GUI toolkits out there, but for our first application we are going to use Tkinter, which is considered somewhat of a <em>standard</em> right now and is installed when pyhon is installed.  Another nice thing about the Tkinter GUI is that it is cross platform and offers a native look and feel on *nix, Windows, and OS X.</p>
<h3>Tkinter Example One</h3>
<p>So lets start off with a simply &#8220;Hello World&#8221; GUI app:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#! /usr/bin/env python
</span><span class="hl-reserved">from </span><span class="hl-identifier">Tkinter </span><span class="hl-reserved">import</span><span class="hl-default"> *

</span><span class="hl-reserved">class </span><span class="hl-identifier">GUIFramework</span><span class="hl-brackets">(</span><span class="hl-identifier">Frame</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the GUI</span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">master</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize</span><span class="hl-quotes">&quot;&quot;&quot;
        
        &quot;&quot;&quot;</span><span class="hl-string">Initialize the base class</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">Frame</span><span class="hl-default">.</span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">master</span><span class="hl-brackets">)
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Display the main window</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">()
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create the Text</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">HelloLabel</span><span class="hl-default"> = </span><span class="hl-identifier">Label</span><span class="hl-brackets">(</span><span class="hl-identifier">master</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello World!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">HelloLabel</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">()
                
</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default"> = </span><span class="hl-identifier">GUIFramework</span><span class="hl-brackets">()
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default">.</span><span class="hl-identifier">mainloop</span><span class="hl-brackets">()</span></pre></div></div>
<p>Running this on OS X results in the following:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/HelloWorld.png" alt="hello world python gui" /></p>
<p>And running it in Windows Xp gives you:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WinPyGUI1.png" alt="hello world python gui" /><br />
<span id="more-11"></span><br />
As you can see the code used to create the GUI is pretty simple and easy to understand, but it is actually more complicated then need be because it uses classes.  But since I&#8217;ll be using classes whenever building a GUI I thought that this was the best starting point.  We start off by importing the Tkinter library into our program using this following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">Tkinter </span><span class="hl-reserved">import</span><span class="hl-default"> *</span></pre></div></div>
<p>After that we create a class called <em>GUIFramework</em>, which is the class that will be used to great the GUI elements in Tkinter and uses the Tkinter <a href="http://www.pythonware.com/library/tkinter/introduction/frame.htm#AEN4819">frame</a> class as its base.  For now all the work that we do is done in the <em>__init__</em> function. </p>
<p>There we first initialize the base class (which will initialize Tkinter) and then tell ourselves to be visible:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialise the base class</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">Frame</span><span class="hl-default">.</span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">master</span><span class="hl-brackets">)

</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Display the main window</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">()</span></pre></div></div>
<p>To display ourselves we use the <a href="http://www.pythonware.com/library/tkinter/introduction/grid.htm">grid geometry manager</a>, the grid geometry manager is a straight forward way to display widgets and position them.  Since we have no other widgets in this example the defaults are fine, take a look at example two for for information on widget placement using the grid function.</p>
<p>Next is the process of creating the <em>HelloWorld</em> <a href="http://www.pythonware.com/library/tkinter/introduction/label.htm">label widget</a>,  which is a member of the <em>GUIFramework</em> class, and setting it to be visible.  It&#8217;s a good idea to make your widgets members of the class in case you need to access them later, but if you&#8217;re sure that you&#8217;ll never have to access them later, you can just create them locally.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">HelloLabel</span><span class="hl-default"> = </span><span class="hl-identifier">Label</span><span class="hl-brackets">(</span><span class="hl-identifier">master</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello World!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">HelloLabel</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">()</span></pre></div></div>
<p>After that all the other processing is done in the &#8220;main&#8221; section of our code where we initialize our class and tell it to enter the &#8220;mainloop&#8221;.    The &#8220;mainloop&#8221; is basically the application responding to events:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default"> = </span><span class="hl-identifier">GUIFramework</span><span class="hl-brackets">()
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default">.</span><span class="hl-identifier">mainloop</span><span class="hl-brackets">()</span></pre></div></div>
<h3>Tkinter Example Two</h3>
<p>Next I&#8217;ll show you a more complicated example, I won&#8217;t go into specifics with this one since it&#8217;s still pretty simple.  But if you have any questions about the following code feel free to ask via a comment.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#! /usr/bin/env python
</span><span class="hl-reserved">from </span><span class="hl-identifier">Tkinter </span><span class="hl-reserved">import</span><span class="hl-default"> *
</span><span class="hl-reserved">import </span><span class="hl-identifier">tkMessageBox

</span><span class="hl-reserved">class </span><span class="hl-identifier">GUIFramework</span><span class="hl-brackets">(</span><span class="hl-identifier">Frame</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the GUI</span><span class="hl-quotes">&quot;&quot;&quot;
    
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">master</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Initialize yourself</span><span class="hl-quotes">&quot;&quot;&quot;
        
        &quot;&quot;&quot;</span><span class="hl-string">Initialise the base class</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">Frame</span><span class="hl-default">.</span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">master</span><span class="hl-brackets">)
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the Window Title</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">master</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Type Some Text</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Display the main window&quot;
        with a little bit of padding</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">(</span><span class="hl-identifier">padx</span><span class="hl-code">=</span><span class="hl-number">10</span><span class="hl-code">,</span><span class="hl-identifier">pady</span><span class="hl-code">=</span><span class="hl-number">10</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">CreateWidgets</span><span class="hl-brackets">()
       
    </span><span class="hl-reserved">def </span><span class="hl-identifier">CreateWidgets</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create all the widgets that we need</span><span class="hl-quotes">&quot;&quot;&quot;
                
        &quot;&quot;&quot;</span><span class="hl-string">Create the Text</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">lbText</span><span class="hl-default"> = </span><span class="hl-identifier">Label</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter Text:</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">lbText</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">(</span><span class="hl-identifier">row</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">column</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-brackets">)
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create the Entry, set it to be a bit wider</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enText</span><span class="hl-default"> = </span><span class="hl-identifier">Entry</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enText</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">(</span><span class="hl-identifier">row</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">column</span><span class="hl-code">=</span><span class="hl-number">1</span><span class="hl-code">, </span><span class="hl-identifier">columnspan</span><span class="hl-code">=</span><span class="hl-number">3</span><span class="hl-brackets">)
        
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create the Button, set the text and the 
        command that will be called when the button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">btnDisplay</span><span class="hl-default"> = </span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Display!</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">command</span><span class="hl-code">=</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Display</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">btnDisplay</span><span class="hl-default">.</span><span class="hl-identifier">grid</span><span class="hl-brackets">(</span><span class="hl-identifier">row</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-code">, </span><span class="hl-identifier">column</span><span class="hl-code">=</span><span class="hl-number">4</span><span class="hl-brackets">)
        
    </span><span class="hl-reserved">def </span><span class="hl-identifier">Display</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when btnDisplay is clicked, displays the contents of self.enText</span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-identifier">tkMessageBox</span><span class="hl-default">.</span><span class="hl-identifier">showinfo</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Text</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">You typed: %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">enText</span><span class="hl-code">.</span><span class="hl-identifier">get</span><span class="hl-brackets">())    
                
</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default"> = </span><span class="hl-identifier">GUIFramework</span><span class="hl-brackets">()
    </span><span class="hl-identifier">guiFrame</span><span class="hl-default">.</span><span class="hl-identifier">mainloop</span><span class="hl-brackets">()</span></pre></div></div>
<p>This creates the following window:<br />
<img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/GuiWnd2.png" alt="hello world python gui" /></p>
<p>That shows this dialog when the button is pressed:<br />
<img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/GuiWnd2Res.png" alt="hello world python gui" /></p>
<p>Links that helped me get through this post:</p>
<ul>
<li><a href="http://www.pythonware.com/library/tkinter/introduction/">http://www.pythonware.com/library/tkinter/introduction/</a></li>
<li><a href="http://infohost.nmt.edu/tcc/help/pubs/tkinter/">http://infohost.nmt.edu/tcc/help/pubs/tkinter/</a></li>
</ul>
<p>If you like this post remember to <a href="http://digg.com/programming/Creating_a_GUI_in_Python_using_Tkinter">digg it</a>.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/02/08/creating-a-gui-in-python-using-tkinter/&title=Creating a GUI in Python using Tkinter&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/02/08/creating-a-gui-in-python-using-tkinter/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Classes</title>
		<link>http://www.learningpython.com/2006/01/28/classes/</link>
		<comments>http://www.learningpython.com/2006/01/28/classes/#comments</comments>
		<pubDate>Sat, 28 Jan 2006 19:19:09 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=12</guid>
		<description><![CDATA[
			
				
			
		
If you are familiar with Object Oriented programming you probably already know what classes are.   If you are unfamiliar with the idea of classes in programming I suggest you give the class topic a read over at wikipedia, it should familiarize you with the idea of a class.  
Once you know what [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F01%2F28%2Fclasses%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F01%2F28%2Fclasses%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>If you are familiar with Object Oriented programming you probably already know what classes are.   If you are unfamiliar with the idea of classes in programming I suggest you give the <a href="http://en.wikipedia.org/wiki/Class_%28object-oriented_programming%29">class topic</a> a read over at wikipedia, it should familiarize you with the idea of a class.  </p>
<p>Once you know what a class is you should read the tutorial over a python.org&#8217;s section on <a href="http://docs.python.org/tut/node11.html">classes in Python</a>.  I&#8217;ll hi-light some of the main points here, but for an in-depth understanding of the way that classes work in Python, it&#8217;s a must read.</p>
<p>First off we&#8217;ll take a look at the syntax of a class:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">classname</span><span class="hl-default">:</span></pre></div></div>
<p><span id="more-12"></span><br />
The term <em>class</em> starts the definition of a class and is then followed by the name of the class.  If the class is derived from another class the syntax is as following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">classname</span><span class="hl-brackets">(</span><span class="hl-identifier">baseclass1</span><span class="hl-code">, </span><span class="hl-identifier">baseclass1</span><span class="hl-code">, ..., </span><span class="hl-identifier">baseclassN</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>Classes can have data members and function members:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TestClass</span><span class="hl-default">:
    </span><span class="hl-identifier">i</span><span class="hl-default"> = </span><span class="hl-number">10</span><span class="hl-default">;
    </span><span class="hl-reserved">def </span><span class="hl-identifier">PrintI</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">i</span></pre></div></div>
<p>One of the things you&#8217;ll notice about the function definition PrintI within the above class is the strange use of the <em>self</em> variable.  What <em>self </em>is, is actually a reference to the class itself, which is why you see that in order to reference the variable <em>i</em> in the <em>PrintI</em> function, <em>self.i</em> is used rather then simply <em>i</em>.  If <em>i</em> was simply used then i would become a local variable in the function. </p>
<p>You can use any term as the first parameters in functions within classes, it does not have to be <em>self</em>, however <em>self</em> has become somewhat of a standard so it&#8217;s recommended that use it.</p>
<p>So now you can reference the above class in the following way:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create an Instance of the class</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">tc</span><span class="hl-default"> = </span><span class="hl-identifier">TestClass</span><span class="hl-brackets">()</span><span class="hl-default">;
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Print out the value of the i variable</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-reserved">print </span><span class="hl-identifier">tc</span><span class="hl-default">.</span><span class="hl-identifier">i
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Call the PrintI function to print out the 
value of the i variable</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">tc</span><span class="hl-default">.</span><span class="hl-identifier">PrintI</span><span class="hl-brackets">()</span></pre></div></div>
<p>The above code would result in (as you might have guessed) the value 10 being written out twice.  There are many situations where you will want to construct your class with some default settings, or set some values.  This is done using the <em>__init__</em> function, which is automatically called ever time you construct, or create an instance of,  a class.  Sin instead of setting <em>i</em>, the way that we did above, we should probably do something like:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">TestClass</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">,</span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">i</span><span class="hl-default"> = </span><span class="hl-identifier">value
    </span><span class="hl-reserved">def </span><span class="hl-identifier">PrintI</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">i</span></pre></div></div>
<p>Where <em>value</em> is an extra parameter was pass to the construction of <em>TestClass</em>: </p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create an Instance of the class</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">tc</span><span class="hl-default"> = </span><span class="hl-identifier">TestClass</span><span class="hl-brackets">(</span><span class="hl-number">23</span><span class="hl-brackets">)</span><span class="hl-default">;</span></pre></div></div>
<p>Classes also support <a href="http://www.python.org/doc/2.4.2/tut/node6.html#SECTION006760000000000000000">docstrings</a> in the same way that functions do.  The docstring can be references in code using the <em>__doc__</em> attribute.</p>
<p>That&#8217;s about it for basic work with classes, for more information I really recommend reading the <a href="http://docs.python.org/tut/node11.html">section on classes</a> in the <a href="http://docs.python.org/tut/tut.html">Python tutorial</a> or any othe the lings below:</p>
<li><a href="http://www.lib.uchicago.edu/keith/courses/python/class/5/">Itroduction to Python &#8211; Classes</a></li>
<li><a href="http://diveintopython.org/object_oriented_framework/defining_classes.html">Dive into Python &#8211; Defining Classes</a></li>
<li><a href="http://www.freenetpages.co.uk/hp/alan.gauld/tutclass.htm">Learning to Program &#8211; Object Oriented Programming</a></li>
<li><a href="http://http://www.python.org/doc/current/tut/node11.html">Pythong.org Tutorial &#8211; Classes</a></li>
<li><a href="http://www.faqts.com/knowledge_base/index.phtml/fid/242">Python classes FAQ</a></li>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/01/28/classes/&title=Classes&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/01/28/classes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
