<?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; gui</title>
	<atom:link href="http://www.learningpython.com/tag/gui/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>AVC: Simplifying your GUI Code</title>
		<link>http://www.learningpython.com/2010/03/14/avc-simplifying-your-gui-code/</link>
		<comments>http://www.learningpython.com/2010/03/14/avc-simplifying-your-gui-code/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 14:44:46 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[avc]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[PyQt]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[wxWidget]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=169</guid>
		<description><![CDATA[
			
				
			
		
Note: This article was first published the April 2008 issue of Python Magazine
By: Mark Mruss
GUI programming, like many other types of programming, can sometimes prove exhausting because you must repeat yourself over and over again. AVC is one tool available to Python GUI programmers that attempts to simplify things by synchronizing application data and GUI [...]]]></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%2F2010%2F03%2F14%2Favc-simplifying-your-gui-code%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F03%2F14%2Favc-simplifying-your-gui-code%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Note: This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/68">April 2008</a> issue of <a href="http://www.pythonmagazine.com/">Python Magazine</a></p>
<p><strong>By: Mark Mruss</strong></p>
<p>GUI programming, like many other types of programming, can sometimes prove exhausting because you must repeat yourself over and over again. <a href="http://avc.inrim.it/html/">AVC</a> is one tool available to Python GUI programmers that attempts to simplify things by synchronizing application data and GUI widgets.</p>
<h2>Introduction</h2>
<p>Every once in a while I find myself browsing the Internet trying to find out what&#8217;s new and exciting in the Python world. Sometimes I browse to find topics for this article; other times mere curiosity draws me across the web. While I was browsing the other day, I stumbled across <em>AVC: the Application View Controller</em> <a href="http://avc.inrim.it/html/">[1]</a>. I was immediately intrigued by it because its’ name is so similar to the Model View Controller (MVC) pattern. Being familiar with the Model View Controller pattern, and admittedly having  struggles with it in the past, I decided to check out AVC to determine if it might be a viable alternative.</p>
<p>After reading about AVC I was intrigued for several reasons. The main reason was the promise of &#8220;a multiplatform, fully automatic, live connection among graphical interface widgets and application variables.&#8221; <a href="http://avc.inrim.it/html/">[2]</a> This means that graphical widgets can be connected to variables and automatically synchronized. One of the (many?) problems with Graphical User Interface (GUI) programming is that you often find yourself doing the same thing over and over again. One of the things that you end of doing over and over again is setting the contents of a widget based on the value of a variable, and then subsequently, setting that variable&#8217;s value based on the current state of the widget. Whenever someone promises me an automatic connection between GUI widgets and my variables, I&#8217;m interested.</p>
<p><span id="more-169"></span></p>
<p>The other reason for investigating AVC is my past struggles with the Model View Controller pattern. I like the decoupling that the MVC pattern seems to provide, but I often feel as though I am needlessly duplicating code in order to stick with the pattern.  I looked into AVC hoping to find a simple framework that will avoid this and guide the separation of my application data from my GUI logic. However in the end, I realized that AVC (in its current state), does not appear to achieve this across all widget toolkits. It does allow you to separate your application from much of the GUI logic that one would normally need, but it does not appear to allow you to fully separate the data from the GUI.</p>
<p>AVC is being developed by Fabrizio Pollastri, and is released under version 3 of the GPL. I was unable to find much information about the project’s future or design objectives. But judging by the release notes, it is still being actively developed.  The project is only at version 0.5 so don’t be surprised if the API (Application Programming Interface) or some of the goals change.  Although relatively new, AVC bears further investigation because it already simplifies your GUI programming and contains the potential to do much more.  In this article, I will introduce some of the main concepts behind AVC, and provide a small, working example using AVC and PyGTK.</p>
<h2>Installing AVC</h2>
<p>AVC is a &#8220;Python module written in pure python&#8221; <a href="http://avc.inrim.it/html/">[3]</a>. This means that AVC is easy to install and does not have any dependencies aside from Python 2.2 or greater. You can download the current version (0.5.0) from the website or, if you are a lucky Linux user like me, you can install via your handy package manger.  If you download the source, you can install it after extraction, using the following command:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">python setup</span><span class="hl-default">.</span><span class="hl-identifier">py install</span></pre></div></div>
<p>Depending on which widget toolkit you plan on using, the following requirements must also be met:</p>
<ul>
<li><strong>GTK+:</strong> PyGTK 2.8 &#8211; 2.10</li>
<li><strong>Qt:</strong> PyQt or PyQt4v3 &#8211; v4</li>
<li><strong>Tk:</strong> Tkinter 2.4</li>
<li><strong>wxWidgets:</strong> wxPython 2.6</li>
</ul>
<p>You can easily install any of the above toolkits using your favourite package manager, a source archive, or a binary installer found on each toolkit’s main website. Once AVC is installed, you can test the installation by importing the <code>avc</code> module from the interactive interpreter. If all goes well you will see something similar to the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">$ </span><span class="hl-identifier">python
Python </span><span class="hl-number">2.4.4 </span><span class="hl-brackets">(</span><span class="hl-comment">#2, Jan  3 2008, 13:36:28)
</span><span class="hl-brackets">[</span><span class="hl-identifier">GCC </span><span class="hl-number">4.2.3 20071123 </span><span class="hl-brackets">(</span><span class="hl-identifier">prerelease</span><span class="hl-brackets">) (</span><span class="hl-identifier">Debian </span><span class="hl-number">4.2.2</span><span class="hl-code">-</span><span class="hl-number">4</span><span class="hl-brackets">)] </span><span class="hl-identifier">on linux2
Type </span><span class="hl-quotes">&quot;</span><span class="hl-string">help</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">copyright</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">credits</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">or </span><span class="hl-quotes">&quot;</span><span class="hl-string">license</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">for </span><span class="hl-identifier">more information</span><span class="hl-code">.
&gt;&gt;&gt; </span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-code">
&gt;&gt;&gt;</span></pre></div></div>
<h2>Widget Support</h2>
<p>In its current state, AVC does not support all widgets available across all toolkits. It does currently support the following widgets:</p>
<ul>
<li>Button</li>
<li>Check Box</li>
<li>Combo Box (Not supported in Tk)</li>
<li>Entry</li>
<li>Label</li>
<li>Radio Button</li>
<li>Slider</li>
<li>Spin Button</li>
<li>Status Bar (Only supported by GTK+ and wxWidgets)</li>
<li>Text View</li>
<li>Toggle Button.</li>
</ul>
<p>The support of each of these widget types is then handled by specific widgets in each toolkit.</p>
<h2>Name-Matching</h2>
<p>In order to automatically synchronize variables and GUI widgets, AVC uses a name-matching technique. AVC supports two methods of name matching. The first method requires that the variable and the widget have the same name. For example, if you have a variable named <code>my_data</code> it will match with a widget also named <code>my_data</code>. In other words, if a variable and a widget have the same name they will be connected and their values synchronized.</p>
<p>The second name-matching technique allows you to connect variables to one or more widgets. Widgets can only be connected to one variable, but variables can be connected to any number of widgets. Using the second name-matching technique, you have a match if the widget name contains a double-underscore (<code>__</code>), <strong>and</strong> the portion before the double-underscore matches the variable name. For example, if you have variable named <code>my_numeric_value</code> and you want to match it with a Label widget and an Entry widget, you do this by naming the widgets as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_numeric_value__label
my_numeric_value__entry</span></pre></div></div>
<p>Again, the text before the &#8220;__&#8221; must match the variable name, and the text after the &#8220;__&#8221; can be whatever you want to differentiate your widgets or ensure uniqueness (if the toolkit requires it).</p>
<h2>A GTK+, PyGTK, and AVC Example</h2>
<p>For this AVC example, I will use the GTK+ widget toolkit and PyGTK. PyGTK a &#8220;is a set of bindings to the GTK+ user interface toolkit for the Python language&#8221; <a href="http://faq.pygtk.org/index.py?req=all#1.1">[4]</a>. This means that it lets us write GUI applications in Python using the GTK+ widget toolkit. To avoid any flame wars: I did not choose GTK+ because it is the best toolkit but because it is the toolkit with which I am the most familiar.  In order to run this example you will need to have PyGTK 2.8 or later installed. You can get the latest version of PyGTK from the PyGTK website. <a href="http://www.pygtk.org/downloads.html">[5]</a></p>
<p>As I mentioned earlier, AVC works with many different widgets types. It also has many different features. I won&#8217;t be covering all of the features or widgets types in this column; if you are interesting in learning about some of these features or how to work with different widgets types, please see the AVC documentation. <a href="http://avc.inrim.it/doc/user_manual.pdf">[6]</a></p>
<p>This example is relatively simple, but it should illustrate some of the basic features of AVC. The example application asks for a person’s name and then displays that name in pop-up dialog. It will have the following features:</p>
<ol>
<li>A <code>gtk.TextView</code> widget to display the person&#8217;s name and allow the name to be edited. The <code>gtk.TextView</code> widget will be synchronised with a variable.</li>
<li>A <code>gtkButton</code> that will pop-up a <code>gtk.MessageDialog</code> to show the person&#8217;s name.</li>
<li>A <code>gtk.Button</code> that will reset the name to the name with which the application was initialized.</li>
</ol>
<p>To begin we need to import all of the modules necessary:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcgtk</span></pre></div></div>
<p><strong>Note</strong>: I am using a <code>gtk.TextView</code> widget instead of a <code>gtk.Entry</code> widget. In its current state, AVC does not propagate changes in <code>gtk.Entry</code> widgets back to the connected variable. I&#8217;m not sure if this is a current limitation or part of the design.</p>
<p>The above code imports the PyGTK module necessary to work with GTK+. It also imports the <code>avcgtk</code> module, which is used to link our &#8220;application variables&#8221; with our GTK+ GUI. Depending on what widget toolkit you use, you will have to use different modules. For example, if you are working with Qt4, you will import:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcqt4</span></pre></div></div>
<p>The next step is to create the &#8220;application&#8221; class. This will be the class that contains the data. In this example it will also create the GUI:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-identifier">avc</span><span class="hl-code">.</span><span class="hl-identifier">avcgtk</span><span class="hl-code">.</span><span class="hl-identifier">AVC</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>Notice that we derive our application from the <code>avcgtk</code> module&#8217;s AVC class. This is the GTK+ specific AVC class with which we will work. We will also create an <code>__init__</code> method in the <code>gtkAVC</code> class. This is where we will initialize the data that will be connected to the GUI and create the GUI via the <code>init_gui</code> method:</p>
<div class="hl-surround" ><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">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-comment">#set the variable and save the initial name
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span><span class="hl-default"> = </span><span class="hl-identifier">name
    self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">name
    </span><span class="hl-comment">#setup GUI
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">init_gui</span><span class="hl-brackets">()</span></pre></div></div>
<p>What we have here is pretty simple. We have the optional parameter <code>name</code> that we store as the current name and as the initial name. We then call the <code>init_gui</code> method that will create the GUI. The contents of the <code>init_gui</code> method can be seen in Listing 1. I won&#8217;t explain most of this code since the majority of it is PyGTK specific. However I will make note of several relevant segments below.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">init_gui</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-comment">#Setup the window and the layout manager
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Window</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">destroy</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">HBox</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">h_layout</span><span class="hl-brackets">)

    </span><span class="hl-comment">#create the widgets
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_label</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Label</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_label</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Frame</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">frame</span><span class="hl-brackets">)
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">ScrolledWindow</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TextView</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</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">name__text_view</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">scrolled_window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_view</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello!</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">hello_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked</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">on_hello_clicked</span><span class="hl-brackets">)
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">reset_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Reset</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">reset_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked</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">on_reset_clicked</span><span class="hl-brackets">)
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">reset_button</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">show_all</span><span class="hl-brackets">()</span></pre></div></div>
<p>The only AVC specific code segment in the <code>init_gui</code> function is where we set the name of the <code>gtk.TextView</code> widget:</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">text_view</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">name__text_view</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>This is all the code that we need to connect the <code>gtk.TextView</code> widget with the <code>name</code> variable that we created at the beginning of the <code>__init__</code> function. (Now, how&#8217;s that for simple?) Notice that the <code>name</code> section of the &#8220;name__text_view&#8221; string will match with the <code>self.name</code> variable. It is also important to note that the variable and the widget are not yet connected. They will become connected when the <code>avc_init</code> method is called.</p>
<p>The other non-AVC related code of note is the connection of both <code>gtk.Button</code> widgets’ clicked signals with signal handlers. We connect the &#8220;hello&#8221; button to the <code>on_hello_clicked</code> method and the &#8220;reset&#8221; button to the <code>on_reset_clicked</code> method.</p>
<p>That&#8217;s it for the <code>init_gui</code> function, now let&#8217;s look at the two signal handlers. The <code>on_hello_clicked</code> method, shown in Listing 2, simply displays the name in a <code>gtk.MessageDialog</code>. What should be interesting to GUI programmers about this function is that instead of reading the data from the <code>gtk.TextView</code> widget, we simply reference <code>self.name</code> for the dialog&#8217;s text. We can do this because <code>self.name</code> and the <code>gtk.TextView</code> widget are connected and their values are always the same.</p>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">close</span><span class="hl-brackets">(</span><span class="hl-identifier">dialog</span><span class="hl-code">, </span><span class="hl-identifier">response</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#Close the dialog on ok
        </span><span class="hl-identifier">dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">window</span><span class="hl-code">
        , </span><span class="hl-number">0</span><span class="hl-code">
        , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_INFO</span><span class="hl-code">
        , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-code">
        , </span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello: %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">name</span><span class="hl-brackets">))
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">response</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">close</span><span class="hl-brackets">)
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span></pre></div></div>
<p>The <code>on_reset_clicked</code> function is also very simple and straightforward. We simply reset the name to the initial name:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_reset_clicked</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-comment">#Reset the name to the initial name
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span></pre></div></div>
<p>Again, notice that we don&#8217;t have to worry about doing anything to the <code>gtk.TextView</code> widget that displays the current name. By simply modifying the data, what is displayed in the GUI will automatically be updated by AVC.</p>
<p>The next and final step in our test application is to create our class instances and actually show the GUI:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">__name__</span><span class="hl-code"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default"> = </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default">.</span><span class="hl-identifier">avc_init</span><span class="hl-brackets">()
    </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Since I am working in a Python file, I perform a simple test to make sure that the file is being launched directly instead of being imported as a module. I then create an instance of the <code>gtkAVC</code> class setting the name to be my name. The <code>avc_init</code> method is then called (which is a member of the <code>avc.avcgtk.AVC</code> class). The <code>avc_init</code> method is where all of the magic happens.  It is where AVC goes through an application&#8217;s variables and connects them to the GUI widgets based upon the name matching technique explained earlier. <code>avc_init</code> must be called <strong>after</strong> all of the data in the &#8220;application&#8221; and the widgets have been created.</p>
<p>The final step in this example, is to run the <code>gtk.main</code> function. This is the &#8220;main loop&#8221; of our PyGTK based application and is standard when working with PyGTK.</p>
<p>The entire code can be seen in Listing 3. When you run the code you will be greeted with something similar to Figure 1. It may not seem like much, but what we have here is a fully functional AVC &#8220;application&#8221;. This simple &#8220;application&#8221; illustrates how easy it is to create an automatic connection between your data and your GUI.</p>
<div id="attachment_172" class="wp-caption alignnone" style="width: 310px"><img src="http://www.learningpython.com/wp-content/uploads/2010/03/Figure1-300x230.png" alt="Figure1" title="Figure1" width="300" height="230" class="size-medium wp-image-172" /><p class="wp-caption-text">Figure1</p></div>
<p><strong>Listing 3</strong></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">import </span><span class="hl-identifier">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcgtk

</span><span class="hl-reserved">class </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-identifier">avc</span><span class="hl-code">.</span><span class="hl-identifier">avcgtk</span><span class="hl-code">.</span><span class="hl-identifier">AVC</span><span class="hl-brackets">)</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">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-comment">#set the variable and save the initial name
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span><span class="hl-default"> = </span><span class="hl-identifier">name
        self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">name
        </span><span class="hl-comment">#setup GUI
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">init_gui</span><span class="hl-brackets">()

    </span><span class="hl-reserved">def </span><span class="hl-identifier">init_gui</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-comment">#Setup the window and the layout manager
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Window</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">destroy</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">HBox</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">h_layout</span><span class="hl-brackets">)

        </span><span class="hl-comment">#create the widgets
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_label</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Label</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_label</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Frame</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">frame</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">ScrolledWindow</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TextView</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</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">name__text_view</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">scrolled_window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_view</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello!</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">hello_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked</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">on_hello_clicked</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">reset_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Reset</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">reset_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked</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">on_reset_clicked</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">reset_button</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">show_all</span><span class="hl-brackets">()

    </span><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">close</span><span class="hl-brackets">(</span><span class="hl-identifier">dialog</span><span class="hl-code">, </span><span class="hl-identifier">response</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-comment">#Close the dialog on ok
            </span><span class="hl-identifier">dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">window</span><span class="hl-code">
            , </span><span class="hl-number">0</span><span class="hl-code">
            , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_INFO</span><span class="hl-code">
            , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-code">
            , </span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello: %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">name</span><span class="hl-brackets">))
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">response</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">close</span><span class="hl-brackets">)
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()

    </span><span class="hl-reserved">def </span><span class="hl-identifier">on_reset_clicked</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-comment">#Reset the name to the initial name
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name

if </span><span class="hl-brackets">(</span><span class="hl-identifier">__name__</span><span class="hl-code"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default"> = </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default">.</span><span class="hl-identifier">avc_init</span><span class="hl-brackets">()
    </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<h2>Benefits and Limitations</h2>
<p>For a project that is little more than one year old (the first release was in January 2007) AVC appears quite stable and ready to be used. This is not to say that AVC is perfect. I did encounter a few issues.</p>
<p>The most notable issue that I encountered is the tightly coupled structure that AVC seems to impose on your application. For a module that tries to simplify the relationship between application data and GUI&#8217;s, this feels like a bit of an issue because. For example, when testing using PyGTK I was able to easily separate the GUI and the &#8220;application&#8221; into separate classes. But when I tried to do the same thing using PyQt4, I encountered an error because the <code>avc_timer</code> function in the <code>avc.avcqt4.AVC</code> module expects that the &#8220;application&#8221; class is itself a <code>QObject</code> (namely the actual <code>QApplication</code>). I find this counterintuitive since being able to separate the data from the GUI-logic seems to be a goal of AVC and similar tools. If you are able to separate the &#8220;application&#8221; fully from the GUI, you can easily connect your &#8220;application&#8221; to different GUI&#8217;s, and (by changing the AVC base class) even different widget toolkits.</p>
<p>I would also be interested in the ability to connect more types of data to more types of widgets. For example, I am interested in synchronizing Python lists with the contents of List boxes and Combo boxes. This is in addition to the current ability to synchronize the selection in the two widgets with integers.</p>
<p>Of course AVC also has a lot going for it. For one, I really like that AVC works with different widget toolkits. I have not seen this very often. It is a real benefit, especially when it comes to people adopting AVC. Hopefully in the future AVC will allow for further separation of the data and the GUI, truly enabling us to use different GUI&#8217;s and different widget toolkits with our data.</p>
<p>What I like most about AVC is its simplicity. I have played around with similar solutions and AVC is one of the leaders in terms of ease of use. I was able to get create a simple AVC based application in almost no time at all. (The time that it did take was spent trying to remember PyGTK.) Much of this has to do with the streamlined nature of AVC. There is very little to configure regardless of what widget toolkit you use. While this simplicity limits what AVC can currently achieve compared to other solutions, it also makes the barrier to entry low and the usage trivial. User friendliness is certainly a good thing in a package that aims to make GUI application development easier.</p>
<h2>Conclusion</h2>
<p>While the data that we worked with in the earlier example wasn&#8217;t that complicated (a simple string), I hope that it illustrates how helpful AVC is if you are working with a large amount of data or data that could be updated by an external source. Instead of having to worry about what widgets or toolkits the data was being displayed in, AVC lets us work with the data and GUI transparently, leaving the synchronization to AVC.</p>
<p>If what AVC offers sounds interesting to you, download it from the AVC website and try it out.  Although it it&#8217;s not there just yet with enough attention, usage, and contributions from the Python community, AVC should reach full-feature status in no time.</p>
<p><a href="http://avc.inrim.it/html/">[1] http://avc.inrim.it/html/</a><br />
<a href="http://avc.inrim.it/html/">[2] http://avc.inrim.it/html/</a><br />
<a href="http://avc.inrim.it/html/">[3] http://avc.inrim.it/html/</a><br />
<a href="http://faq.pygtk.org/index.py?req=all#1.1">[4] http://faq.pygtk.org/index.py?req=all#1.1</a><br />
<a href="http://www.pygtk.org/downloads.html">[5] http://www.pygtk.org/downloads.html</a><br />
<a href="http://avc.inrim.it/doc/user_manual.pdf">[6] http://avc.inrim.it/doc/user_manual.pdf</a></p>
<p><strong>Note:</strong> If you haven&#8217;t already, please check out my <a href="http://www.learningpython.com/2010/03/04/poll-python-version/">Python version poll</a>.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2010/03/14/avc-simplifying-your-gui-code/&title=AVC: Simplifying your GUI Code&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/2010/03/14/avc-simplifying-your-gui-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>An Introduction to PyQt: creating GUIs with Python&#8217;s QT bindings</title>
		<link>http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/</link>
		<comments>http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 19:21:46 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[PyQt]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[gui]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=88</guid>
		<description><![CDATA[
			
				
			
		
By: Mark Mruss
Note: This article was first published the December 2007 issue of Python Magazine
While the command line will never cease to be useful, nothing will impress your friends more than your latest python masterpiece wrapped up in a slick cross-platform Graphical User Interface (GUI). This tutorial will show you how to create a simple [...]]]></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%2F2008%2F09%2F20%2Fan-introduction-to-pyqt%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F09%2F20%2Fan-introduction-to-pyqt%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the December 2007 issue of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>While the command line will never cease to be useful, nothing will impress your friends more than your latest python masterpiece wrapped up in a slick cross-platform Graphical User Interface (GUI). This tutorial will show you how to create a simple GUI in Python using PyQt4.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#InstallingPyQt4">Installing PyQt4</a></li>
<li><a href="#FirstApplication">Your First PyQt4 Application</a></li>
<li><a href="#TheMainWindow">The Main Window</a></li>
<li><a href="#AddingSomeWidgets">Adding Some Widgets</a></li>
<li><a href="#SignalHandling">Signal Handling</a></li>
<li><a href="#DisplayingAMessage">Displaying a Message</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-88"></span></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>While writing console applications and modules using Python can be very enjoyable, I think that almost everyone learning Python eventually wants to do one thing: create a application with a full Graphical User Interface (GUI). Fortunately for Python users, there are a few options available to achieve this. One of the more interesting options is PyQt4, Python bindings for the fourth version of the famous cross platform application development API Qt.</p>
<p>Qt, owned by Trolltech software, is probably most famous as the foundation for the KDE window manager on Linux. PyQt4, and PyQt version 3, were created and are maintained by Riverbank software.  Qt and PyQt4 are both open source and free for open source applications, but if you wish to develop commercial applications you will need to purchase the commercial versions of both Qt and PyQt4.</p>
<p>One of the best features of Qt is that it is a cross platform library which means that it gives you easy access to the three main desktop environments: Linux, Windows, and OS X. This is an important requirement for me because when I&#8217;m developing a small open source application I want it available on as many platforms as possible. The nice thing about Qt’s latest version, Qt4, is that it also gives your GUI a native look and feel on the different operating systems.</p>
<p>This article will create a simple application to introduce you to the basic features of PyQt4. The application will consist of a single window that does the following: accepts user input, responds to a button click, and displays a message using a pop-up dialog.</p>
<h2><a name="InstallingPyQt4">Installing PyQt4</a></h2>
<p>Before installing PyQt4 you need to have Python 2.5 or newer and Qt version 4 installed. You can download Python 2.5 from the main Python website.<a href="#1">[1]</a> Qt version 4 is available from the TrollTech website&#8217;s Downloads section.<a href="#2">[2]</a> Installing PyQt4 on Linux, Windows, or OS X is relatively easy, and I know since I installed it on each of them. You can download the different PyQt4 packages from the Riverbank website, including an all in one (Qt version 4 included) installer for Windows.<a href="#3">[3]</a> There are also installation instructions in the PyQt4 online documentation that are worth a read if you are new to installing software from source.<a href="#4">[4]</a> If you are using a modern Linux distribution, you may want to consider using your package manager to install PyQt4 as it should being along all the necessary dependencies for you.</p>
<h2><a name="FirstApplication">Your First PyQt4 Application</a></h2>
<p>Now that you have PyQT4 properly installed, let’s dive right in and create an application. The first step is to start a new Python file, I called mine <code>PyQt4Intro.py</code> but you can call it whatever you like. Set it up using the following code:</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">PyQt4

</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-comment"># Someone is launching this directly
	</span><span class="hl-reserved">pass</span></pre></div></div>
<p>If you&#8217;ve read any of my other columns, you may recognize this code as a general template that I use for my Python projects. The major difference in this example is that we import PyQt4. After you have set your file up run the code. If all goes well nothing will happen. If you do get an error, something like the following, it probably means that PyQt4 is not installed properly:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>ImportError: No module named PyQt4</pre></div></div>
<p>Remember that PyQT4 requires Python 2.5. If you have Python 2.5 and older versions of Python installed, try specifying <code>python2.5</code> when you run the script:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>python2.5 PyQt4Intro.py</pre></div></div>
<p>Now that we have everything in order, let&#8217;s create and show a window. After all this is a GUI tutorial! If you are creating a GUI application using PyQt4 (of course, you can also create a non-GUI application using PyQt4), you will need to create a <code>QApplication</code> instance. </p>
<p>The PyQt4 documentation provides a great description of the &#8220;QApplication&#8221; class: &#8220;The QApplication class manages the GUI application&#8217;s control flow and main settings. It contains the main event loop, where all events from the window system and other sources are processed and dispatched. It also handles the application&#8217;s initialization and finalization, and provides session management. It also handles most system-wide and application-wide settings. For any GUI application that uses Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any time.&#8221;<a href="#5">[5]</a></p>
<p>What we need to do is create the one and only <code>QApplication</code> instance for our application. To do this, we will import two new modules:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui</span></pre></div></div>
<p>The first line imports the <code>sys</code> module. This is needed to initialize the <code>QApplication</code>. The second line imports the <code>QtGui</code> module. It allows us to reference <code>QApplication</code> and other <code>QtGui</code> components. </p>
<p>In our main block, we will add the following code:</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-comment"># Someone is launching this directly
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<p>This will create the <code>QApplication</code> instance, initialized with the command-line parameters that may be passed to our script. This is a necessary parameter to the <code>QApplication</code> class and is the reason that we imported the <code>sys</code> module.  The next call is to the <code>exec</code> function which &#8220;enters the main event loop and waits until exit() is called or the main widget is destroyed&#8221;.<a href="#6">[6] </a></p>
<p>If you run the entire script at this point, which I don&#8217;t necessarily recommend since it will seem to hang, you will be running a PyQt4 application. You won&#8217;t see anything since there is no visible component. However, the script will continue to run in its main loop instead of returning right after being executed. If you do decide to run this script, use CTRL+Z to exit.</p>
<h2><a name="TheMainWindow">The Main Window</a></h2>
<p>GUI applications without a visible component are not that useful so let&#8217;s add a window to our application. We will do this by sub-classing the <code>QMainWindow</code> class. The <code>QMainWindow</code> class &#8220;provides a framework for building an application&#8217;s user interface. Qt has &#8220;QMainWindow&#8221; and its related classes for main window management. &#8220;QMainWindow&#8221; has its own layout to which you can add &#8220;QToolBars&#8221;, &#8220;QDockWindows&#8221;, a &#8220;QMenuBar&#8221;, and a &#8220;QStatusBar&#8221;.&#8221;<a href="#7">[7]</a></p>
<p><strong>Note:</strong> There are other ways to create a visible window. For example you could use a <code>QWidget</code> to accomplish much of what we are going to do. I chose to use the <code>QMainWindow</code> since it provides an application framework that you might want to use when building a full GUI application.</p>
<p>We can subclass the <code>QMainWindow</code> as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-brackets">)</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">win_parent</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-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-brackets">)</span></pre></div></div>
<p>Then in the main block we can create and show our main window like this:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment">#The Main window
</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
</span><span class="hl-comment"># Enter the main loop
</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<p>The entire source code thus far is found in Listing 1. When you run the code, you will finally be greeted with your very first PyQt4 window. It will look something similar to Figure 1.</p>
<p><strong>Listing 1</strong></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">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-brackets">)</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">win_parent</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-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</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">win_parent</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-comment"># Someone is launching this directly
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_91" class="wp-caption alignnone" style="width: 216px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure1.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure1.png" alt="Figure 1" title="Figure 1" width="206" height="128" class="size-medium wp-image-91" /></a><p class="wp-caption-text">Figure 1</p></div>
<h2><a name="AddingSomeWidgets">Adding Some Widgets</a></h2>
<p>A blank window is only slightly more useful then an invisible oen. Therefore our next step is to add some functionality to our window by adding some interactive widgets. In order to do this, we will set the central widget of our main window and use a &#8220;geometry manager&#8221; (or &#8220;layout manager&#8221;) class to manage the positioning of our widgets.</p>
<p>We will add a new function to our <code>HelloWindow</code> class called <code>create_widgets</code> where we will create all of our widgets. We will call this function from the <code>__init__</code> function. The first step in the <code>create_widgets</code> function is to create a widget that will serve as the &#8220;central widget&#8221; for our main window. As mentioned earlier, the <code>QMainWindow</code> class already has a built-in layout making it easy to add menus, toolbars, and other items common to applications. <code>QMainWindow</code> classes also have a &#8220;central widget&#8221; which you can think of as the main part of the application. More to the point, the &#8220;central widget&#8221; is not the toolbars, menu, or docking panes, but the actual functional area of the application. For a greater description of the &#8220;central widget&#8221; see the PyQt4 website.<a href="#8">[8]</a></p>
<p>We will create and set our &#8220;central widget&#8221; using the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)</span></pre></div></div>
<p>So far this won&#8217;t do anything, since we still have not added anything interactive. To add interactivity, we must add widgets to our &#8220;central widget&#8221;. Rather than place the widgets in static positions, we will use a layout manager to automatically position and adjust our widgets. If you are at all familiar with modern GUI toolkits, the idea of a layout manager should be familiar to you. They serve as a way to &#8220;pack&#8221; widgets into an area where their positions will be relative to each other and to the window. When you resize the window (or area), geometry manager&#8217;s will automatically adjust the size and positions of their child widgets to accommodate the new size.</p>
<p>We will be creating three widgets in our simple application: </p>
<p>1. A <code>QLabel</code> widget to display some static text.<br />
2. A <code>QLineEdit</code> widget to let the user enter some text into an edit field.<br />
3. A <code>QPushButton</code> button widget that will pop up a dialog to display a message when the user clicks on it.</p>
<p>We will create the widgets using the following code. Notice that in the creation of the <code>QLabel</code> and <code>QPushButton</code> widgets we are also setting the text that will appear on each widget. (We can do the same for the <code>QLineEdit</code>, but for now we&#8217;ll leave it blank):</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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-comment">#Widgets
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next, we will create a <code>QHBoxLayout</code> instance to serve as the central widget&#8217;s layout manager. The <code>QHBoxLayout</code> class is a specific type of layout manager that lays widgets out, and manage their positions, in the horizontal direction. Once we have created the <code>QHBoxLayout</code> instance, we will add our three widgets to it. Adding widgets to a <code>QHBoxLayout</code> will pack them from left to right:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Horizontal layout
</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)</span></pre></div></div>
<p>The last step in our widget creation is to set <code>h_box</code> as the layout manager for our central widget:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Create central widget, add layout, and set
</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)</span></pre></div></div>
<p>The entire code can be seen in Listing 2. When you run this code, you will finally be greeted with a window containing actual widgets. This is illustrated in Figure 2.</p>
<p><strong>Listing 2</strong></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">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-brackets">)</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">win_parent</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-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()

	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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-comment">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</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-comment"># Someone is launching this directly
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_92" class="wp-caption alignnone" style="width: 296px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure2.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure2.png" alt="Figure 2" title="Figure 2" width="286" height="128" class="size-medium wp-image-92" /></a><p class="wp-caption-text">Figure 2</p></div>
<h2><a name="SignalHandling">Signal Handling</a></h2>
<p>Responding to the user’s interaction with the GUI is something that must be done in all GUI applications. Therefore the next step in constructing a GUI application is signal or event handling. If you are unfamiliar with these terms you can thing of it his way: when the end user interacts with your GUI, her interaction will causes signals to be sent to your application. So if she clicks on a button the clicked() signal will be sent. If your application wants to do something when that button is clicked, then you will have to handle that widgets <code>clicked()</code> signal.  In our example, we are going to show a pop up a dialog when the user clicks on our button widget.</p>
<p>I find connecting to signals in PyQt4 a bit odd because of a built in macro that needs to be called but the process is relatively easy so I shouldn&#8217;t complain too much. The idea is similar to that of other Python GUI toolkits: you connect functions that you have written to signals or events that are emitted by a widget. So whenever a widget emits a signal that has been connected to a function, that function will be called.</p>
<p><strong>Note:</strong> Qt goes a bit further with the idea of built-in &#8220;slots&#8221; but for the sake of this tutorial we will be ignoring them. For more information on &#8220;slots&#8221; please see the PyQt4 documentation.</p>
<p>In order for the &#8220;QPushButton&#8221; to do something when pushed, we have to connect a function in our <code>HelloWindow</code> class with the <code>clicked</code> signal.  To do this, we need to call the <code>QObject</code> classes <code>connect</code> static function. We must tell it three things: </p>
<p>1. The <code>QWidget</code> that will emit the signal.<br />
2. The signal that we want to connect to.<br />
3. The function that should be called when the <code>QWidget</code> emits the signal.</p>
<p>In our example, we will do this like so:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#connect signal
</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
	, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</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">on_hello_clicked</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Note:</strong> We could just as easily have called <code>self.connect</code> since a <code>QMainWindow</code> is a descendant of the <code>QObject</code> class.</p>
<p><code>QtCore.SIGNAL</code> is a macro that you have to use for the second parameter. It accepts the signal name as a string (in this case <code>clicked()</code>) and converts it into an object that is required for the signal connection. The documentation is a bit sparse regarding exactly what the macro does, but luckily for us we don&#8217;t really need to know the details.</p>
<p>In order for this code to compile, we also have to import the <code>QtCore</code> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore</span></pre></div></div>
<p>We also have to add a new function to the <code>HelloWindow</code> class. This is the function <code>on_hello_clicked</code> that will respond to the <code>clicked()</code> signal:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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-quotes">&quot;</span><span class="hl-string">Clicked</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>When you run the code in Listing 3, you will see &#8220;Clicked&#8221; printed out to the command line every time you click the &#8220;Push Me!&#8221; button.</p>
<p><strong>Listing 3</strong></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">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-brackets">)</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">win_parent</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-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()


	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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-comment">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

		</span><span class="hl-comment">#connect signal
		</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
			, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</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">on_hello_clicked</span><span class="hl-brackets">)


		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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-quotes">&quot;</span><span class="hl-string">Clicked</span><span class="hl-quotes">&quot;
		
</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-comment"># Someone is launching this directly
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<h2><a name="DisplayingAMessage">Displaying a Message</a></h2>
<p>Now that we have a function connected to the clicking of the button widget we need to read the text from the <code>QLineEdit</code> widget and display it to the user. Fortunately both tasks are quite easy in PyQt4. </p>
<p>In order to get the text from a <code>QLineEdit</code> widget, the <code>QLineEdit</code> classes member function <code>displayText</code> needs to be called. The <code>displayText</code> function simply returns the contents of the <code>QLineEdit</code> widget.</p>
<p>Showing a pop-up dialog using PyQt4 is just as easy as getting the contents of a <code>QLineEdit</code> widget, thanks to the <code>QMesssageBox</code> classes static function <code>information</code>.  This function allows you to set the title, text and what buttons are on a simple &#8220;information dialog&#8221;.  Calling it from our PyQt4 application in response to the button click is very simple:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-default">.</span><span class="hl-identifier">information</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello!</span><span class="hl-quotes">&quot;</span><span class="hl-code">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello %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">hello_edit</span><span class="hl-code">.</span><span class="hl-identifier">displayText</span><span class="hl-brackets">()</span><span class="hl-code">
		, </span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-code">.</span><span class="hl-identifier">Ok</span><span class="hl-brackets">)</span></pre></div></div>
<p>In this code, we call the information function, set its title text to be &#8220;Hello!&#8221;, set its main message to be &#8220;Hello &#8221; followed by the contents of the <code>hello_edit</code> <code>QInputEdit</code>, and give it one button, an &#8220;ok&#8221; button. All of the code is found in Listing 4. What this looks like running on Linux, Windows and OS X can be seen in Figure 3, Figure 4, and Figure 5 respectively.</p>
<p><strong>Listing 4</strong></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">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-brackets">)</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">win_parent</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-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()


	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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-comment">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</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">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

		</span><span class="hl-comment">#connect signal
		</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
			, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</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">on_hello_clicked</span><span class="hl-brackets">)


		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-default">.</span><span class="hl-identifier">information</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">
			, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello!</span><span class="hl-quotes">&quot;</span><span class="hl-code">
			, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello %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">hello_edit</span><span class="hl-code">.</span><span class="hl-identifier">displayText</span><span class="hl-brackets">()</span><span class="hl-code">
			, </span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-code">.</span><span class="hl-identifier">Ok</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-comment"># Someone is launching this directly
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</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-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_93" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure3.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure3-300x217.png" alt="Figure 3" title="Figure 3" width="300" height="217" class="size-medium wp-image-93" /></a><p class="wp-caption-text">Figure 3</p></div>
<div id="attachment_94" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure4.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure4-300x220.png" alt="Figure 4" title="Figure 4" width="300" height="220" class="size-medium wp-image-94" /></a><p class="wp-caption-text">Figure 4</p></div>
<div id="attachment_95" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure5.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure5-300x230.png" alt="Figure 5" title="Figure 5" width="300" height="230" class="size-medium wp-image-95" /></a><p class="wp-caption-text">Figure 5</p></div>
<h2><a name="Conclusion">Conclusion</a></h2>
<p>That&#8217;s it for this quick introduction to PyQt4. All-in-all, I was pleasantly surprised by PyQt4. Even during my first foray into the toolkit, I found it very straightforward and was able to get things going in a matter of minutes. Granted, what I was trying to accomplish was pretty simple, but it&#8217;s always a good sign when doing something simple is easy!</p>
<p>You should now have enough information to go and create your very own &#8220;GUIfied&#8221; applications. Of course, there is much, much more to PyQt4 than I have covered in this tutorial. But if you use the PyQt4 documentation and the fundamentals from this tutorial, you shouldn&#8217;t have much trouble moving forward.</p>
<p><a name="1">[1]</a> <a href="http://www.python.org/download/">http://www.python.org/download/</a><br />
<a name="2">[2]</a> <a href="http://www.riverbankcomputing.co.uk/pyqt/download.php">http://www.riverbankcomputing.co.uk/pyqt/download.php</a><br />
<a name="3">[3]</a> <a href="http://trolltech.com/downloads">http://trolltech.com/downloads</a><br />
<a name="4">[4]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html#installing-pyqt">http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html#installing-pyqt</a><br />
<a name="5">[5]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html">http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html</a><br />
<a name="6">[6]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html#exec">http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html#exec</a><br />
<a name="7">[7]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details">http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details</a><br />
<a name="8">[8]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details">http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details</a></p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/&title=An Introduction to PyQt: creating GUIs with Python's QT bindings&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/2008/09/20/an-introduction-to-pyqt/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Building an Application with PyGTK and Glade</title>
		<link>http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/</link>
		<comments>http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/#comments</comments>
		<pubDate>Tue, 30 May 2006 18:41:03 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[glade]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[PyWine]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=25</guid>
		<description><![CDATA[
			
				
			
		
After working with PyGTK and Glade for my first tutorial, I decided to write another more complex tutorial but I couldn&#8217;t think of a topic (Note: If you have any suggestions for any tutorials or posts I&#8217;d love to hear them) so I decided to work on creating a simple application and hopefully useful topics [...]]]></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%2F05%2F30%2Fbuilding-an-application-with-pygtk-and-glade%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F05%2F30%2Fbuilding-an-application-with-pygtk-and-glade%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>After working with PyGTK and Glade for my first tutorial, I decided to write another more complex tutorial but I couldn&#8217;t think of a topic (<strong>Note</strong>: If you have any suggestions for any tutorials or posts I&#8217;d love to hear them) so I decided to work on creating a simple application and hopefully useful topics would arise from there.</p>
<p>The idea I came up with (which will hopefully be simple) is to create a program that will allow me to keep track of the different types of wine that I drink and how much I like them.  It&#8217;s something I&#8217;ve wanted to write for a while so I thought it would be good to combine learning PyGTK and doing it.</p>
<p>I&#8217;m going to call the project PyWine.  The full source and Glade file for this tutorial can be found <a href="http://www.learningpython.com/sources/PyWine.tar.gz">here</a></p>
<p>The first thing to do is start a new Glade project in the projects directory called PyWine.  Create a new Window, call it &#8220;mainWindow,&#8221; and set the title to be &#8220;PyWine&#8221;.  Then add a handler to the destroy signal just like in the first tutorial.</p>
<p>Next I add a Vertical Box to the Window with 4 rows, (from top to bottom) one row for a Menu bar, one row for a Toolbar, one row for a Tree or List View, and the final row for a Status Bar.  Name the Tree View &#8220;wineView&#8221;</p>
<p><img style="margin: 10px 10px 10px 10px;" src="http://www.learningpython.com/images/pywine_01/pywine_01.png" border="0" alt="Python Glade" /></p>
<p><span id="more-25"></span></p>
<p>The Tree or List View that we added to the window will be used to display the wines information to the user.  So the first thing that we are going to want to do is allow the user to add a wine to the dialog.  To do this we are going to use a menu command and a Toolbar button.</p>
<p>The first thing to add is a toolbar button.  To do this simply select the toolbar button in the Pallet and click on the toolbar that we added to the window.  This should add a strange looking button to your toolbar.  Now we are going to edit the toolbar buttons properties on the Widget tab.  We&#8217;ll set its name to be &#8220;tbAddWine&#8221;, its label to be &#8220;Add Wine&#8221;, and it&#8217;s icon to be the stock add icon.</p>
<p><strong>Note:</strong> A user Thomas Says: &#8220;With glade 3 the toolbar buttons aren’t available in the palette. You have to add buttons to the toolbar by right clicking in the toolbar, selecting add and then add the toolbar button.&#8221;</p>
<p><img style="margin: 10px 10px 10px 10px;" src="http://www.learningpython.com/images/pywine_01/pywine_02.png" border="0" alt="Python Glade" /></p>
<p>Now we&#8217;ll add a handler for the tbAddWine button&#8217;s click event but this time instead of calling it the default &#8220;on_tbAddWine_clicked&#8221; we&#8217;ll call the handler &#8220;on_AddWine&#8221;.</p>
<h3>Adding to the Menu Bar</h3>
<p>Now we are going to work on the menu, since we want people to be able to add items from the taskbar button or from the Menu Bar.  So click on the Menu Bar in the window and go to the Widget tab in the properties window.  Then click on the &#8220;Edit Menus&#8230;&#8221; button to edit the Menu Bar.</p>
<p>Now click the Add button to add a new top level menu item, and sets it&#8217;s label to be &#8220;_Add&#8221;.  Then select the Add item in the menu list and click the &#8220;Add Child&#8221; button, this will create a sub-menu within the Add menu.  Set the new items label to be &#8220;_Wine&#8221; and set it&#8217;s handler to be: &#8220;on_AddWine&#8221;.</p>
<p>You&#8217;ll notice that the handled for the Add toolbar button clicked event and the <code>Add | Wine</code> menu activation are the same.  This is because both of those two widgets will be performing the exact same task, adding a wine to our wine list.</p>
<p><a href="http://www.learningpython.com/images/pywine_01/pywine_03.png"><img style="margin: 10px 10px 10px 10px;" src="http://www.learningpython.com/images/pywine_01/small_pywine_03.png" border="0" alt="Python Glade Menu Editor" /></a></p>
<p>So what&#8217;s going to happen when the user clicks on the Add Wine button or selects <code>Add | Wine</code> from the menu, is a dialog will pop up allowing them to enter in details about the wine.  If they choose the &#8220;Ok&#8221; button to end the dialog the wine information that they entered will be added to the ListView.</p>
<h3>Creating a dialog</h3>
<p>So the next thing that we need to do is create the dialog that the user will use to add a new wine.  For this example we&#8217;ll keep things pretty simple and let the user enter the wine name, the winery, the year it was bottled, and the grape variety.</p>
<p>So to create a new dialog simply click the Dialog button on the Glade Palette window.  This should bring up the New Dialog window, in it choose the &#8220;Standard button layout&#8221; option with Cancel and Ok as the buttons.  Now set the dialogs name to be &#8220;wineDlg&#8221; and it&#8217;s window title to be &#8220;Add Wine&#8221;.</p>
<p>Next we will use a table to lay things out in our wineDlg, add the table to your dialog (in the normal way that you add widgets to a window) and set the number or rows to be 4 and the number of columns to be 2.  Then we&#8217;ll fill in the spaces of the table with Label and Text Entry widgets until the dialog looks something like this:</p>
<p><img style="margin: 10px 10px 10px 10px;" src="http://www.learningpython.com/images/pywine_01/pywine_04.png" border="0" alt="Python Glade Menu Editor" /></p>
<p>I added three pixels of spacing between the rows of the table, this setting can be found on the widget tab of the table&#8217;s properties.  If you are having trouble selecting the table you can select <code>View | Show Widget Tree</code> from the menu in the main Glade window and select the table in the widget tree.  Or you can hold down the SHIFT key and left click on the widgets in the table, this will allow you to cycle through the widgets on the dialog.</p>
<p>Now we are going to have to name all of the edit fields on the dialog, name then: enWine, enWinery, enGrape, and enYear.</p>
<h3>The Python Code</h3>
<p>Now we are going to take that code and get it working, we&#8217;ll call our python file pywine.py and create it in our /projects/PyWine directory (the same directory where we created our glade files).  The following is the basic code that we will use (most of it taken form the first <a href="http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/">PyGTk/Glade tutorial</a>):</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">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">try</span><span class="hl-default">:
</span><span class="hl-reserved">import </span><span class="hl-identifier">pygtk
pygtk</span><span class="hl-default">.</span><span class="hl-identifier">require</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">2.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">except</span><span class="hl-default">:
</span><span class="hl-reserved">pass
try</span><span class="hl-default">:
</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade
</span><span class="hl-reserved">except</span><span class="hl-default">:
</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-number">1</span><span class="hl-brackets">)

</span><span class="hl-reserved">class </span><span class="hl-identifier">pyWine</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the PyWine application</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-brackets">)</span><span class="hl-default">:

</span><span class="hl-comment">#Set the Glade file
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">gladefile</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">pywine.glade</span><span class="hl-quotes">&quot;
</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">mainWindow</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-comment">#Create our dictionay and connect it
</span><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_mainWindow_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main_quit</span><span class="hl-default">
, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_AddWine</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">OnAddWine</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><span class="hl-reserved">def </span><span class="hl-identifier">OnAddWine</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">Called when the use wants to add a wine</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">OnAddWine</span><span class="hl-quotes">&quot;

</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">wine</span><span class="hl-default"> = </span><span class="hl-identifier">pyWine</span><span class="hl-brackets">()
</span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>There are a few new additions to this code, one is the handler for the on_AddWine signal, if you run this code you&#8217;ll notice that &#8220;OnAddWine&#8221; will be printed out when you click the Add Wine button and when you select <code>Add | Wine</code> from the menu.  The other new addition to the code is that we pass the name of the main window to gtk.glade.XML.  This lets us load only that window and it&#8217;s children.</p>
<p>The next thing that we are going to create is a Wine class that we will use to store the wines information:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">Wine</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This class represents all the wine information</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">wine</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">winery</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">grape</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">year</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-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">wine
self</span><span class="hl-default">.</span><span class="hl-identifier">winery</span><span class="hl-default"> = </span><span class="hl-identifier">winery
self</span><span class="hl-default">.</span><span class="hl-identifier">grape</span><span class="hl-default"> = </span><span class="hl-identifier">grape
self</span><span class="hl-default">.</span><span class="hl-identifier">year</span><span class="hl-default"> = </span><span class="hl-identifier">year</span></pre></div></div>
<p>Pretty simple, the next thing that we are going to create is a class that we&#8217;ll use for our wineDlg dialog, we&#8217;ll call it wineDialog:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">wineDialog</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This class is used to show wineDlg</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">wine</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">winery</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">grape</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">year</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-comment">#setup the glade file
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">gladefile</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">pywine.glade</span><span class="hl-quotes">&quot;
</span><span class="hl-comment">#setup the wine that we will return
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">Wine</span><span class="hl-brackets">(</span><span class="hl-identifier">wine</span><span class="hl-code">,</span><span class="hl-identifier">winery</span><span class="hl-code">,</span><span class="hl-identifier">grape</span><span class="hl-code">,</span><span class="hl-identifier">year</span><span class="hl-brackets">)</span></pre></div></div>
<p>The next thing we need to do is add a function to our wineDialog class that will load the wineDialog widget from the glade file and show it.  We will also want this function to return the result of the dialog, this will be a gtk.RESPONSE, you can read more about these at the <a href="http://www.pygtk.org/pygtk2reference/gtk-constants.html#gtk-response-type-constants">PyGTK website</a>.</p>
<p>Here is the run function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">run</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">This function will show the wineDlg</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-comment">#load the dialog from the glade file
</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">wineDlg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Get the actual dialog widget
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">wineDlg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Get all of the Entry Widgets and set their text
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWine</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enWine</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">enWine</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">wine</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWinery</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enWinery</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">enWinery</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">winery</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enGrape</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enGrape</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">enGrape</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">grape</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enYear</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enYear</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">enYear</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">year</span><span class="hl-brackets">)

</span><span class="hl-comment">#run the dialog and store the response
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()
</span><span class="hl-comment">#get the value of the entry fields
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWine</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">winery</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWinery</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">grape</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enGrape</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">year</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enYear</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()

</span><span class="hl-comment">#we are done with the dialog, destroy it
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()

</span><span class="hl-comment">#return the result and the wine
</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">result</span><span class="hl-default">,</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span></pre></div></div>
<p>You&#8217;ll notice that we load the dialog form the glade file in the same way that we load the main window.  We call gtk.glade.XML() and pass it the name of the widget that we want to load.  This will automatically show the Dialog (in the same way that it does our main window) but that&#8217;s not good enough for us, we want the run function to wait until the user has exited the dialog before we return to the caller.  To do that we call get the dialog widget from the widget tree (<code>self.dlg = self.wTree.get_widget("wineDlg")</code>) and we call the <a href="http://www.pygtk.org/pygtk2reference/class-gtkdialog.html#method-gtkdialog--run">GTkDialogs run function</a>.  I&#8217;ll let the PyGTk documentation describe what this function does:</p>
<blockquote><p>The run() method blocks in a recursive main loop until the dialog either emits the &#8220;response&#8221; signal, or is destroyed. If the dialog is destroyed, the run() method returns gtk.RESPONSE_NONE; otherwise, it returns the response ID from the &#8220;response&#8221; signal emission. Before entering the recursive main loop, the run() method calls the gtk.Widget.show() on the dialog for you. Note that you still need to show any children of the dialog yourself.</p>
<p>During the run() method, the default behavior of &#8220;delete_event&#8221; is disabled; if the dialog receives a &#8220;delete_event&#8221;, it will not be destroyed as windows usually are, and the run() method will return gtk.RESPONSE_DELETE_EVENT. Also, during the run() method the dialog will be modal. You can force the run() method to return at any time by calling response() to emit the &#8220;response&#8221; signal. Destroying the dialog during the run() method is a very bad idea, because your post-run code won&#8217;t know whether the dialog was destroyed or not.</p>
<p>After the run() method returns, you are responsible for hiding or destroying the dialog as needed.</p></blockquote>
<p>The Ok button will return gtk.RESPONSE_OK and the Cancel button will return gtk.RESPONSE_CANCEL, for the most part we only care about the wine that is returned by this dialog if the user clicks the Ok button.</p>
<p>You can also see that we get the GTKEntry widgets from the dialog in order to get and set their text.  All-in-all this function is pretty simple.</p>
<h3>Tree Views and List Stores</h3>
<p>Now that we have the wine the the user wanted to add to the list we need actually add it to the <a href="http://www.pygtk.org/pygtk2reference/class-gtktreeview.html">gtk.TreeView</a>.</p>
<p>The main feature of GTKTreeViews is that they display their data in whatever way their model tells them to.  They can use a <a href="http://www.pygtk.org/pygtk2reference/class-gtkliststore.html">gkt.ListStore</a>, <a href="http://www.pygtk.org/pygtk2reference/class-gtktreestore.html">gtk.TreeStore</a>, <a href="http://www.pygtk.org/pygtk2reference/class-gtktreemodelsort.html">gtk.TreeModelSort</a>, or a <a href="http://www.pygtk.org/pygtk2reference/class-pygtkgenerictreemodel.html">gtk.GenericTreeModel</a>.  For this example we&#8217;re going to be using a gtk.ListStore.</p>
<p>The relationships between Tree View&#8217;s and Models is a bit complicated but once you start using it you&#8217;ll begin to understand why they did it this way.  In a very basic form the Model represents the Data, and the Tree View is simply a way to display the data.  So you can have multiple views display the same data (model) in totally different ways.  From the <a href="http://developer.gnome.org/doc/API/2.0/gtk/TreeWidget.html">GTk+ reference manual</a>:</p>
<blockquote><p>To create a tree or list in GTK+, use the GtkTreeModel interface in conjunction with the GtkTreeView widget. This widget is designed around a Model/View/Controller  design and consists of four major parts:<br />
The tree view widget (GtkTreeView)<br />
The view column (GtkTreeViewColumn)<br />
The cell renderers (GtkCellRenderer etc.)<br />
The model interface (GtkTreeModel)</p>
<p>The View is composed of the first three objects, while the last is the Model. One of the prime benefits of the MVC design is that multiple views can be created of a single model. For example, a model mapping the file system could be created for a file manager. Many views could be created to display various parts of the file system, but only one copy need be kept in memory.</p></blockquote>
<p>The first thing we need to do is add some code to the __init__ function of the pyWine class right after we auto-connect the dictionary to the widget tree:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Here are some variables that can be reused later
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cWine</span><span class="hl-default"> = </span><span class="hl-number">0
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cWinery</span><span class="hl-default"> = </span><span class="hl-number">1
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cGrape</span><span class="hl-default"> = </span><span class="hl-number">2
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cYear</span><span class="hl-default"> = </span><span class="hl-number">3

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sWine</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Wine</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sWinery</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Winery</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sGrape</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Grape</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sYear</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Year</span><span class="hl-quotes">&quot;

</span><span class="hl-comment">#Get the treeView from the widget Tree
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineView</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">wineView</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Add all of the List Columns to the wineView
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sWine</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cWine</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sWinery</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cWinery</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sGrape</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cGrape</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sYear</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cYear</span><span class="hl-brackets">)</span></pre></div></div>
<p>This code is pretty straight forward, first we create a few variables that act as defines for us (so that we can easily change things around later) then we get our gtk.TreeView from the widget tree.  After that we call a new function to add the columns that we need in the list.  AddWineListColumn just a quick function that stops us from having to replicate the column create code each time:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">title</span><span class="hl-code">, </span><span class="hl-identifier">columnId</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 adds a column to the list view.
First it create the gtk.TreeViewColumn and then set
some needed properties</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-identifier">column</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TreeViewColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">CellRendererText</span><span class="hl-brackets">()</span><span class="hl-code">
, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-identifier">columnId</span><span class="hl-brackets">)
</span><span class="hl-identifier">column</span><span class="hl-default">.</span><span class="hl-identifier">set_resizable</span><span class="hl-brackets">(</span><span class="hl-reserved">True</span><span class="hl-brackets">)
</span><span class="hl-identifier">column</span><span class="hl-default">.</span><span class="hl-identifier">set_sort_column_id</span><span class="hl-brackets">(</span><span class="hl-identifier">columnId</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineView</span><span class="hl-default">.</span><span class="hl-identifier">append_column</span><span class="hl-brackets">(</span><span class="hl-identifier">column</span><span class="hl-brackets">)</span></pre></div></div>
<p>This code is a bit more complicated, first we create a new <a href="http://www.pygtk.org/pygtk2reference/class-gtktreeviewcolumn.html">gtk.TreeViewColumn</a> that uses a <a href="http://www.pygtk.org/pygtk2reference/class-gtkcellrenderertext.html">gtk.CellRendererText</a> as it&#8217;s <a href="http://www.pygtk.org/pygtk2reference/class-gtkcellrenderer.html">gtk.CellRenderer</a>.  Here is a bit more general information from the <a href="http://developer.gnome.org/doc/API/2.0/gtk/TreeWidget.html">GTK+ reference manual</a>:</p>
<blockquote><p>Once the GtkTreeView widget has a model, it will need to know how to display the model. It does this with columns and cell renderers.</p>
<p>Cell renderers are used to draw the data in the tree model in a way. There are a number of cell renderers that come with GTK+ 2.x, including the GtkCellRendererText, GtkCellRendererPixbuf and the GtkCellRendererToggle. It is relatively easy to write a custom renderer.</p>
<p>A GtkTreeViewColumn is the object that GtkTreeView uses to organize the vertical columns in the tree view. It needs to know the name of the column to label for the user, what type of cell renderer to use, and which piece of data to retrieve from the model for a given row.</p></blockquote>
<p>So basically what we are doing is creating a column with a specific title, specifying that it will use the gtk.CellRendererText (to display simply text),  and telling it which item in the model it is attached to.  The we make it resizable and allow the user to sort the list by clicking on a columns header.  After that all we do is add the column to the View.</p>
<p>Now that that&#8217;s done we need to create our Model, we&#8217;ll do this back in the __init__ function of the pyWine class:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#Create the listStore Model to use with the wineView
self.wineList = gtk.ListStore(str, str, str, str)
#Attatch the model to the treeView
self.wineView.set_model(self.wineList)</pre></div></div>
<p>Basically we simply create a gtk.ListStore and tell it that it will have four items, all of which will be strings.  Then we attach the model to the view and that&#8217;s all the initialization that we need to do for out gtk.TreeView.</p>
<h3>Putting it all Together</h3>
<p>The last thing that we need to do is write the OnAddWine function (called from the menu or the toolbar button) in the pyWine class.  It&#8217;s a pretty simple function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">OnAddWine</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">Called when the use wants to add a wine</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-comment">#Create the dialog, show it, and store the results
</span><span class="hl-identifier">wineDlg</span><span class="hl-default"> = </span><span class="hl-identifier">wineDialog</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">newWine</span><span class="hl-default"> = </span><span class="hl-identifier">wineDlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()

</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">result</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-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">The user clicked Ok, so let's add this
wine to the wine list</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineList</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">newWine</span><span class="hl-code">.</span><span class="hl-identifier">getList</span><span class="hl-brackets">())</span></pre></div></div>
<p>So we create an instance of our wineDialog and then we run it storing the result and the wine information that the user entered.  Then we check to see if the result was gtk.RESPONSE_OK (the user clicked on the Ok button) and if it is we then add the wine information to our gtk.ListStore which will automatically be displayed in our gtk.TreeView since the two are connected.</p>
<p>We make use of the simple getList function in our wine class to make this slightly easier to read:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">getList</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">This function returns a list made up of the
wine information.  It is used to add a wine to the
wineList easily</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-reserved">return </span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">wine</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">winery</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">grape</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">year</span><span class="hl-brackets">]</span></pre></div></div>
<p><a href="http://www.learningpython.com/images/pywine_01/pywine_05.png"><img style="margin: 10px 10px 10px 10px;" src="http://www.learningpython.com/images/pywine_01/small_pywine_05.png" border="0" alt="Python PyGTK PyWine Glade" /></a></p>
<p>That&#8217;s about it for this sample application, granted it doesn&#8217;t save any of the information or anything like that yet, but it does outline some of the initial steps to creating a full pyGTk application.</p>
<p>The full source and Glade file can be found <a href="http://www.learningpython.com/sources/PyWine.tar.gz">here</a> you can also browse the full source below:</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">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">try</span><span class="hl-default">:
</span><span class="hl-reserved">import </span><span class="hl-identifier">pygtk
pygtk</span><span class="hl-default">.</span><span class="hl-identifier">require</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">2.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">except</span><span class="hl-default">:
</span><span class="hl-reserved">pass
try</span><span class="hl-default">:
</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade
</span><span class="hl-reserved">except</span><span class="hl-default">:
</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-number">1</span><span class="hl-brackets">)

</span><span class="hl-reserved">class </span><span class="hl-identifier">pyWine</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is an PyWine application</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-brackets">)</span><span class="hl-default">:

</span><span class="hl-comment">#Set the Glade file
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">gladefile</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">pywine.glade</span><span class="hl-quotes">&quot;
</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">mainWindow</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-comment">#Create our dictionay and connect it
</span><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_mainWindow_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main_quit</span><span class="hl-default">
, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_AddWine</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">OnAddWine</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><span class="hl-comment">#Here are some variables that can be reused later
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cWine</span><span class="hl-default"> = </span><span class="hl-number">0
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cWinery</span><span class="hl-default"> = </span><span class="hl-number">1
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cGrape</span><span class="hl-default"> = </span><span class="hl-number">2
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">cYear</span><span class="hl-default"> = </span><span class="hl-number">3

</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sWine</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Wine</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sWinery</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Winery</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sGrape</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Grape</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">sYear</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Year</span><span class="hl-quotes">&quot;

</span><span class="hl-comment">#Get the treeView from the widget Tree
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineView</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">wineView</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Add all of the List Columns to the wineView
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sWine</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cWine</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sWinery</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cWinery</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sGrape</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cGrape</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">sYear</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cYear</span><span class="hl-brackets">)

</span><span class="hl-comment">#Create the listStore Model to use with the wineView
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineList</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">ListStore</span><span class="hl-brackets">(</span><span class="hl-identifier">str</span><span class="hl-code">, </span><span class="hl-identifier">str</span><span class="hl-code">, </span><span class="hl-identifier">str</span><span class="hl-code">, </span><span class="hl-identifier">str</span><span class="hl-brackets">)
</span><span class="hl-comment">#Attache the model to the treeView
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineView</span><span class="hl-default">.</span><span class="hl-identifier">set_model</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">wineList</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">AddWineListColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">title</span><span class="hl-code">, </span><span class="hl-identifier">columnId</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 adds a column to the list view.
First it create the gtk.TreeViewColumn and then set
some needed properties</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-identifier">column</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TreeViewColumn</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">CellRendererText</span><span class="hl-brackets">()</span><span class="hl-code">
, </span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-identifier">columnId</span><span class="hl-brackets">)
</span><span class="hl-identifier">column</span><span class="hl-default">.</span><span class="hl-identifier">set_resizable</span><span class="hl-brackets">(</span><span class="hl-reserved">True</span><span class="hl-brackets">)
</span><span class="hl-identifier">column</span><span class="hl-default">.</span><span class="hl-identifier">set_sort_column_id</span><span class="hl-brackets">(</span><span class="hl-identifier">columnId</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineView</span><span class="hl-default">.</span><span class="hl-identifier">append_column</span><span class="hl-brackets">(</span><span class="hl-identifier">column</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">OnAddWine</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">Called when the use wants to add a wine</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-comment">#Cteate the dialog, show it, and store the results
</span><span class="hl-identifier">wineDlg</span><span class="hl-default"> = </span><span class="hl-identifier">wineDialog</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">newWine</span><span class="hl-default"> = </span><span class="hl-identifier">wineDlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()

</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">result</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-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">The user clicked Ok, so let's add this
wine to the wine list</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wineList</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">newWine</span><span class="hl-code">.</span><span class="hl-identifier">getList</span><span class="hl-brackets">())

</span><span class="hl-reserved">class </span><span class="hl-identifier">wineDialog</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This class is used to show wineDlg</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">wine</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">winery</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">grape</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">year</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-comment">#setup the glade file
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">gladefile</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">pywine.glade</span><span class="hl-quotes">&quot;
</span><span class="hl-comment">#setup the wine that we will return
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">Wine</span><span class="hl-brackets">(</span><span class="hl-identifier">wine</span><span class="hl-code">,</span><span class="hl-identifier">winery</span><span class="hl-code">,</span><span class="hl-identifier">grape</span><span class="hl-code">,</span><span class="hl-identifier">year</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">run</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">This function will show the wineDlg</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-comment">#load the dialog from the glade file
</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">wineDlg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Get the actual dialog widget
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">wineDlg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Get all of the Entry Widgets and set their text
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWine</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enWine</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">enWine</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">wine</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWinery</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enWinery</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">enWinery</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">winery</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enGrape</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enGrape</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">enGrape</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">grape</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enYear</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">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enYear</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">enYear</span><span class="hl-default">.</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">wine</span><span class="hl-code">.</span><span class="hl-identifier">year</span><span class="hl-brackets">)

</span><span class="hl-comment">#run the dialog and store the response
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()
</span><span class="hl-comment">#get the value of the entry fields
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWine</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">winery</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enWinery</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">grape</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enGrape</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default">.</span><span class="hl-identifier">year</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enYear</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()

</span><span class="hl-comment">#we are done with the dialog, destory it
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()

</span><span class="hl-comment">#return the result and the wine
</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">result</span><span class="hl-default">,</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine

</span><span class="hl-reserved">class </span><span class="hl-identifier">Wine</span><span class="hl-default">:
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This class represents all the wine information</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">wine</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">winery</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">grape</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">year</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-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wine</span><span class="hl-default"> = </span><span class="hl-identifier">wine
self</span><span class="hl-default">.</span><span class="hl-identifier">winery</span><span class="hl-default"> = </span><span class="hl-identifier">winery
self</span><span class="hl-default">.</span><span class="hl-identifier">grape</span><span class="hl-default"> = </span><span class="hl-identifier">grape
self</span><span class="hl-default">.</span><span class="hl-identifier">year</span><span class="hl-default"> = </span><span class="hl-identifier">year

</span><span class="hl-reserved">def </span><span class="hl-identifier">getList</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">This function returns a list made up of the
wine information.  It is used to add a wine to the
wineList easily</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-reserved">return </span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">wine</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">winery</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">grape</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">year</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">wine</span><span class="hl-default"> = </span><span class="hl-identifier">pyWine</span><span class="hl-brackets">()
</span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>The next installment of the PyWine tutorial: <a href="http://www.learningpython.com/2006/09/02/extending-our-pygtk-application/">Extending our PyGTK Application</a> is available.</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/&title=Building an Application with PyGTK and Glade&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/05/30/building-an-application-with-pygtk-and-glade/feed/</wfw:commentRss>
		<slash:comments>90</slash:comments>
		</item>
	</channel>
</rss>
