<?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; avc</title>
	<atom:link href="http://www.learningpython.com/tag/avc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Wed, 21 Sep 2011 03:08:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<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 [...]]]></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&amp;b=2" 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>
]]></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>
	</channel>
</rss>

