<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>wxpython &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/wxpython/</link>
	<description>Feed of posts on WordPress.com tagged "wxpython"</description>
	<pubDate>Thu, 24 Dec 2009 04:07:30 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[wxGrid does not update after a change on PyGridTableBase]]></title>
<link>http://pythonhaven.wordpress.com/2009/12/01/wxgrid-does-not-update-after-a-change-on-pygridtablebase/</link>
<pubDate>Wed, 02 Dec 2009 03:03:14 +0000</pubDate>
<dc:creator>Federico</dc:creator>
<guid>http://pythonhaven.wordpress.com/2009/12/01/wxgrid-does-not-update-after-a-change-on-pygridtablebase/</guid>
<description><![CDATA[Hi, I have continued my experiments with the fantastic wxPython library. Today I had to create a sim]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi, I have continued my experiments with the fantastic wxPython library.</p>
<p>Today I had to create a simple grid, so I followed some tutorials and read some documentation on how to use wx.grid.Grid along with wx.grid.PyGridTableBase, in a very MVC-ish fashion. The thing is, that I correctly set up both (you can look up tutorials online on how to use them, or the fantastic <a href="http://www.manning.com/rappin/" target="_blank">wxPython in Action</a> book (which was published back in 2006, making it a little bit old, but very a very useful and educational resource nonetheless). But when invoking the AppendRows or DeleteRows on the grid, I saw no change in the Grid&#8217;s presentation (although I double checked that the table&#8217;s AppendRows and DeleteRows where called accordingly).</p>
<p>But thanks to the wonders of the lazyweb, I found my answer in this very useful post:</p>
<p><a href="http://groups.google.com/group/wxpython-users/msg/f02fb345ef0b35cf" target="_blank">http://groups.google.com/group/wxpython-users/msg/f02fb345ef0b35cf</a></p>
<p>So, all I had to do was to send the corresponding message  on my table&#8217;s AppendRows and DeleteRows methods and all worked just fine.</p>
<p>Hope you find that useful too.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Announcing Podzel]]></title>
<link>http://louistaylor.wordpress.com/2009/11/26/5/</link>
<pubDate>Thu, 26 Nov 2009 16:50:24 +0000</pubDate>
<dc:creator>louistaylor</dc:creator>
<guid>http://louistaylor.wordpress.com/2009/11/26/5/</guid>
<description><![CDATA[Hello!, this is my first real post. I will say something about my latest project. It is a system for]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hello!, this is my first real post.</p>
<p>I will say something about my latest project.</p>
<p>It is a system for writing soil descriptions for use in  archaeology. It will be written in python using wxpython for the GUI, this will allow the program to be used on many different OS&#8217;s. It will probably be form-based.</p>
<p>The name is going to be Podzel, or pyPodzel.</p>
<p>If I get the time from doing coursework etc. I will write this.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Hello World! Qt Jambi]]></title>
<link>http://olliwang.com/2009/10/14/hello-world-qt-jambi/</link>
<pubDate>Wed, 14 Oct 2009 09:46:42 +0000</pubDate>
<dc:creator>Olli Wang</dc:creator>
<guid>http://olliwang.com/2009/10/14/hello-world-qt-jambi/</guid>
<description><![CDATA[Let me clear first. I am a Python guy, most of my projects are written in Python programming languag]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Let me clear first. I am a Python guy, most of my projects are written in Python programming language. I only had a few small projects written in Java before, I was never a Java guy. However, I do know the power of Java and now, I think it&#8217;s time to take advantage of Java, for powerful GUI toolkit.</p>
<p>People who want to develop GUI applications in Python always come into a question, &#8220;Which GUI toolkit should I use?&#8221; I tried Tk a few years ago, which comes with Python standard library, but definitely is not a good choice for large projects. Then I switched to wxPython, which is much better than Tk, but I was still unsatisfying with its GUI design tool. Finally, I met Qt.</p>
<p>Qt probably is the best GUI toolkit right there in my opinion. Though there are some Python bindings for Qt like PyQt and PySide, I found that both of them are not useful for me because PyQt is still only available under GPL and commercial licenses even though Qt is available under LGPL license since version 4.5, and PySide just seems not ready for Windows and Mac users.</p>
<p>Finally, I decided to use Qt Jambi, which is the Qt library made available for Java, and is officially supported by Nokia Corporation. My original thought was to use Qt Jambi with Jython, so I can take advantage of both Java and Python, and able to develop my applications under LGPL license.</p>
<p>The first step to a new programming language or library is always a simple &#8220;Hello World!&#8221; application, but I found that I was in trouble when I was following the official documentation, and that&#8217;s why I wrote this article. Here&#8217;s my working environment:</p>
<li>OS: Mac OS X 10.6.1 (Snow Leopard)</li>
<li>Java version: 1.6.0_15</li>
<li>Qt Jambi: qtjambi-mac-lgpl-4.5.2_01</li>
<p>Before you start writing your &#8220;Hello World&#8221; application. You should make sure everything is working fine, this could be done by launching the Demo Launcher application included in Qt Jambi. Go open a Terminal window and change directory to the Qt Jambi installation directory. Then try to execute the `qtjambi.sh` script. If something is going wrong, simply open the `qtjambi.sh` file and find a line near the end of the file:</p>
<pre class="brush: bash;">java -XstartOnFirstThread -cp $CP com.trolltech.launcher.Launcher</pre>
<p>Then, add `-d32` after `java` like this:</p>
<pre class="brush: bash;">java -d32 -XstartOnFirstThread -cp $CP com.trolltech.launcher.Launcher</pre>
<p>Now execute the `qtjambi.sh` script again and everything should work fine now.</p>
<p>Next, we need to setup the environment for our Jambi applications. I made this by adding some lines to `.profile` file under my user&#8217;s home directory. You need to create one if you don&#8217;t have it yet. Once you have this file, add following lines to the button of the file:</p>
<pre class="brush: bash;"># Qt Jambi
export QTDIR=/Users/olliwang/workspace/qtjambi-mac-lgpl-4.5.2_01
export DYLD_LIBRARY_PATH=$QTDIR/lib:$DYLD_LIBRARY_PATH
export QT_PLUGIN_PATH=$QTDIR/plugins
for lib in $(ls $QTDIR/qtjambi*.jar); do
    CLASSPATH=$lib:$CLASSPATH
done
export CLASSPATH</pre>
<p>Note that only the `QTDIR` variable located in second line should be modified to point to your Qt Jambi installation directory. After you done, we can start make our &#8220;Hello World&#8221; application now.</p>
<p>Before you write your &#8220;Hello World&#8221; application, you need to choose a directory to place your Java source code, not the Qt Jambi installation directory, please. I created a new directory and switched directory to it in my Terminal window. Now you can create a file called &#8220;HelloWorld.java&#8221; and write the following code (borrowed from the Qt Jambi official documentation):</p>
<pre class="brush: java;">import com.trolltech.qt.gui.*;

public class HelloWorld
{
    public static void main(String[] args)
    {
        QApplication.initialize(args);
        QPushButton hello = new QPushButton(&#34;Hello World!&#34;);
        hello.resize(120, 40);
        hello.setWindowTitle(&#34;Hello World&#34;);
        hello.show();
        QApplication.exec();
    }
}</pre>
<p>After saving that file, back to your Terminal window, and compile the source code by running</p>
<pre class="brush: bash;">javac HelloWorld.java</pre>
<p>Finally, you can execute the application by running</p>
<pre class="brush: bash;">java -d32 -XstartOnFirstThread HelloWorld</pre>
<p>And the result should look like this:<br />
<img src="http://olliwang.wordpress.com/files/2009/10/qtjambi_hellowrold.png" alt="qtjambi_hellowrold" title="qtjambi_hellowrold" width="200" height="142" class="alignnone size-full wp-image-273" /><br />
Done!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[wxPython in Action]]></title>
<link>http://esal.wordpress.com/2009/10/12/wxpython-in-action/</link>
<pubDate>Mon, 12 Oct 2009 08:37:50 +0000</pubDate>
<dc:creator>esal</dc:creator>
<guid>http://esal.wordpress.com/2009/10/12/wxpython-in-action/</guid>
<description><![CDATA[wxPython in Action Noel Rappin &amp; Robin Dunn]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><strong>wxPython in Action</strong></p>
<p style="text-align:center;"><strong><br />
</strong></p>
<p style="text-align:center;">Noel Rappin &#38; Robin Dunn</p>
<p><img class="aligncenter size-full wp-image-956" title="wxPython in Action - Noel Rappin &#38; Robin Dunn" src="http://esal.wordpress.com/files/2009/10/wxpython-in-action-noel-rappin-robin-dunn.jpg" alt="wxPython in Action - Noel Rappin &#38; Robin Dunn" width="243" height="300" /></p>
<p style="text-align:center;"><span style="color:#0000ff;"><a href="http://www.ziddu.com/download/6735060/wxPythoninAction-NoelRappinRobinDunn.pdf.html"><img src="http://bse.depdiknas.go.id/images_gif/download.gif" border="0" alt="" width="91" height="31" /></a></span></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[wx.Frame cambio de estilo]]></title>
<link>http://pymanimal.wordpress.com/2009/10/11/wx-frame-cambio-de-estilo/</link>
<pubDate>Sun, 11 Oct 2009 20:49:39 +0000</pubDate>
<dc:creator>dan5sanf</dc:creator>
<guid>http://pymanimal.wordpress.com/2009/10/11/wx-frame-cambio-de-estilo/</guid>
<description><![CDATA[Al crear una wx.Frame, class Frame(wx.Frame): def __init__(self, *args, **kwds): #MyFrame.__init__ k]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Al crear una wx.Frame,</p>
<pre><code>class Frame(wx.Frame):
    def __init__(self, *args, **kwds):
        #MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)</code></pre>
<p>esta tendra el estilo wx.DEFAULT_FRAME_STYLE.<br />
<img src="http://pymanimal.wordpress.com/files/2009/10/pantallazo-ventana-default.png?w=300" alt="Pantallazo-Ventana Default" title="Pantallazo-Ventana Default" width="300" height="241" class="aligncenter size-medium wp-image-155" /><br />
Este es una suma de estilos basicos: wx.MAXIMIZE_BOX &#124; wx.MINIMIZE_BOX &#124; wx.RESIZE_BORDER &#124;wx.SYSTEM_MENU &#124; wx.CAPTION &#124; wx.CLOSE_BOX.<br />
Para cambiar un estilo individual en una composición de estilo se usa el operador or &#8216;^&#8217;.<br />
Necesito crear una ventana basada en el estilo default pero que no pueda cambiar su tamaño.<br />
Para ello al estilo default le quito maximizar , minimizar y que no sea redimencionable la composición quedaría asi:<br />
kwds["style"]=wx.DEFAULT_FRAME_STYLE^(wx.MINIMIZE_BOX&#124;wx.MAXIMIZE_BOX &#124;wx.RESIZE_BORDER))<br />
Esto permitiría ver una ventana de este tipo:<br />
<img src="http://pymanimal.wordpress.com/files/2009/10/pantallazo-relaxtives-busqueda.png?w=300" alt="Pantallazo-Relaxtives - Busqueda" title="Pantallazo-Relaxtives - Busqueda" width="300" height="121" class="aligncenter size-medium wp-image-159" /></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[How to get XP Styles on wxPython apps made with py2exe]]></title>
<link>http://pythonhaven.wordpress.com/2009/10/07/how-to-get-xp-styles-on-wxpython-apps-made-with-py2exe/</link>
<pubDate>Wed, 07 Oct 2009 15:37:44 +0000</pubDate>
<dc:creator>Federico</dc:creator>
<guid>http://pythonhaven.wordpress.com/2009/10/07/how-to-get-xp-styles-on-wxpython-apps-made-with-py2exe/</guid>
<description><![CDATA[Let me begin with this: wxPython is fantastic! I could write a moderately simple app in ~17 hours wh]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Let me begin with this: wxPython is fantastic! I could write a moderately simple app in ~17 hours which automates a task that is normally done manually loading data into a web form. The app consists on custom wizard classes, access to web resources (requesting and parsing) and session management with cookies. I&#8217;m impressed that I could finish the application, with no previous knowledge on any of the aforementioned subjects, in such a short time span.</p>
<p>Publicity aside, I faced a little problem. I packed the python application into an executable that didn&#8217;t require a full python install using the <a href="http://www.py2exe.org/" target="_blank">py2exe</a> extension, after reading the guide on how to get <a href="http://wiki.wxpython.org/py2exe" target="_blank">py2exe to work with wxPython</a>. My first problem was some silly issue with some MSCV*.dll files:</p>
<pre style="padding-left:30px;">*** finding dlls needed ***
error: MSVCP90.dll: No such file or directory</pre>
<p>After a quick read on several places, I found a simple solution for this problem,<a href="http://koobmeej.blogspot.com/2009/08/python-26-py2exe-and-vc-runtime-issues.html" target="_blank"> ignoring the dll file when building  the executables</a>.</p>
<p>With that solved, I could successfully build and launch my application. The less obvious problem was, that even though the application launched it looked ugly! Here&#8217;s a screenshot on what I was getting when running the generated exe vs running the .py file directly:</p>
<p><img class="aligncenter size-full wp-image-77" title="normal_theme-vs-xp_theme" src="http://pythonhaven.wordpress.com/files/2009/10/normal_theme-vs-xp_theme.jpg" alt="normal_theme-vs-xp_theme" width="510" height="196" /></p>
<p>Hideous indeed. The problem was that for some reason the application was not using XP Themes when drawing the application&#8217;s widgets, and after some reading I discovered that there are some serious issues regarding Python2.6 (the version I&#8217;m using), wxPython and py2exe when it comes to <a href="http://en.wikipedia.org/wiki/Side-by-Side_Assembly" target="_blank">manifests</a>. Long story short, I had to associate a correct manifest to my exe file, and after lurking around my Python installs, I found a manifest that wxPython creates for Python that served my needs:</p>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;?xml version=&#8217;1.0&#8242; encoding=&#8217;UTF-8&#8242; standalone=&#8217;yes&#8217;?&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;assembly xmlns=&#8217;urn:schemas-microsoft-com:asm.v1&#8242; manifestVersion=&#8217;1.0&#8242;&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;trustInfo xmlns=&#8221;urn:schemas-microsoft-com:asm.v3&#8243;&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;security&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;requestedPrivileges&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;requestedExecutionLevel level=&#8217;asInvoker&#8217; uiAccess=&#8217;false&#8217; /&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/requestedPrivileges&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/security&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/trustInfo&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;dependency&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;dependentAssembly&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;assemblyIdentity</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">type=&#8217;win32&#8242;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">name=&#8217;Microsoft.VC90.CRT&#8217;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">version=&#8217;9.0.21022.8&#8242;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">processorArchitecture=&#8217;*&#8217;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">publicKeyToken=&#8217;1fc8b3b9a1e18e3b&#8217; /&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/dependentAssembly&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/dependency&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;dependency&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;dependentAssembly&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;assemblyIdentity</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">type=&#8221;win32&#8243;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">name=&#8221;Microsoft.Windows.Common-Controls&#8221;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">version=&#8221;6.0.0.0&#8243;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">processorArchitecture=&#8221;*&#8221;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">publicKeyToken=&#8221;6595b64144ccf1df&#8221;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">language=&#8221;*&#8221; /&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/dependentAssembly&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/dependency&#62;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:286px;width:1px;height:1px;">&#60;/assembly&#62;</div>
<pre style="padding-left:30px;">&#60;?xml version='1.0' encoding='UTF-8' standalone='yes'?&#62;
&#60;assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'&#62;
  &#60;trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"&#62;
    &#60;security&#62;
      &#60;requestedPrivileges&#62;
        &#60;requestedExecutionLevel level='asInvoker' uiAccess='false' /&#62;
      &#60;/requestedPrivileges&#62;
    &#60;/security&#62;
  &#60;/trustInfo&#62;
  &#60;dependency&#62;
    &#60;dependentAssembly&#62;
      &#60;assemblyIdentity
     type='win32'
     name='Microsoft.VC90.CRT'
     version='9.0.21022.8'
     processorArchitecture='*'
     publicKeyToken='1fc8b3b9a1e18e3b' /&#62;
    &#60;/dependentAssembly&#62;
  &#60;/dependency&#62;
  &#60;dependency&#62;
    &#60;dependentAssembly&#62;
      &#60;assemblyIdentity
         type="win32"
         name="Microsoft.Windows.Common-Controls"
         version="6.0.0.0"
         processorArchitecture="*"
         publicKeyToken="6595b64144ccf1df"
         language="*" /&#62;
    &#60;/dependentAssembly&#62;
  &#60;/dependency&#62;
&#60;/assembly&#62;</pre>
<p>Both the &#8220;Microsoft.VC90.CRT&#8221; and &#8220;Microsoft.Windows.Common-Controls&#8221; assemblies are important. The first one is mandatory for Python &#62;= 2.6 is built with Visual Studio 2008, and the second one is the one that links our app to the dlls that provide the nice XP Theme widgets.</p>
<p>Just loaded that text into a string (called manifest in my case) in my setup.py file and passed it as an  argument to the setup function like this:</p>
<pre>setup(windows=[{
               'script':"app.py",
               'other_resources' : [(24, 1, manifest)]
               }],
        name = "My App",
        version="0.1"
    )</pre>
<p>Easy as pie <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p>Hope you find this useful!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Grid ComboBox MySQL]]></title>
<link>http://pymanimal.wordpress.com/2009/09/06/gridcomboboxmysql/</link>
<pubDate>Sun, 06 Sep 2009 03:17:20 +0000</pubDate>
<dc:creator>dan5sanf</dc:creator>
<guid>http://pymanimal.wordpress.com/2009/09/06/gridcomboboxmysql/</guid>
<description><![CDATA[Hacer lista con consulta a db Cambio del diseño; como los datos de la primera columna están en la ba]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong><br />
<h3>Hacer lista con consulta a db</h3>
<p></strong><br />
Cambio del diseño; como los datos de la primera columna están en la base de datos (apellido, nombre y documento) se decidió colocar dentro de la grilla un combobox donde seleccionar estos datos del alumno.<br />
La segunda columna de la grilla quedo igual, con un ComboBox dentro.<br />
Para hacer esto se conecta a la db y se  hace la consulta.</p>
<pre><code>
<h3>tChoiceEditor = wx.grid.GridCellChoiceEditor(['Padre ',
 'Madre','Tio/a ','Primo/a','Hermano/a', 'Madrina',
'Padrino','Vecino/a'] , allowOthers=True)
 c.execute('''select apellidos, nombres, documento from
 alumnos order by apellidos''')
        q = c.fetchall()
        c.close() </h3>

</code></pre>
<p>Luego se crea una lista vacia &#8216;lista&#8217;, se recorre la variable q, que tiene los datos  del fetchall a la db con un for buscando por el indice de q(q[0]) cada dato en la lista.</p>
<pre><code>
<h3>lista = []
        for i in q:
            lista.append(i[0]+" "+ i[1]+" "+ i[2])</h3>

</code></pre>
<p> Se carga a la lista que luego va a usar el tChoiceEditor2 para mostrar en el ComboBox que esta dentro de la grilla.</p>
<pre><code>
<h3>tChoiceEditor2 = wx.grid.GridCellChoiceEditor(lista, allowOthers=True)
        #Asignar a los editores de la célula  la  fila y la columna.
        self.grid_parientes.SetCellEditor(0, 1, tChoiceEditor)
        self.grid_parientes.SetCellEditor(0, 0, tChoiceEditor2)
        #lista
        # Mostrar el tercer elemento de la lista en la celda ChoiceEditor
        #en este caso esta vacia, asi que no aparecera nada
        self.grid_parientes.SetCellValue(0, 1, self.grid_parientes.list[0][5])</h3>

</code></pre>
<p> El código completo y funcional de este formulario se llama <a href="http://code.google.com/p/relaxtives/source/browse/trunk/ingreso_datos.py#">ingreso_datos.py</a> y es parte del proyecto <a href="http://code.google.com/p/relaxtives/">relaxtives</a>.<br />
<img src="http://pymanimal.wordpress.com/files/2009/09/pantallazo-ingreso-de-datos.png?w=300" alt="Pantallazo-Ingreso de datos" title="Pantallazo-Ingreso de datos" width="300" height="221" class="aligncenter size-medium wp-image-168" /></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Combo Box dentro una gridGrid]]></title>
<link>http://pymanimal.wordpress.com/2009/08/26/combo-box-dentro-una-gridgrid/</link>
<pubDate>Wed, 26 Aug 2009 02:40:20 +0000</pubDate>
<dc:creator>dan5sanf</dc:creator>
<guid>http://pymanimal.wordpress.com/2009/08/26/combo-box-dentro-una-gridgrid/</guid>
<description><![CDATA[Como la lista editable que agrega filas de la entrada anterior, tiene en la segunda columna varios d]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Como la lista editable que agrega filas de la entrada anterior, tiene en la segunda columna  varios datos pre establecidos, se penso poner un combo box con todas las opciones.<br />
<img src="http://pymanimal.wordpress.com/files/2009/08/form2.png?w=262" alt="form2" title="form2" width="262" height="300" class="aligncenter size-medium wp-image-129" /><br />
Se describe brevemente en los comentarios del codigo como se implemento este agregado
<pre><code>
<h3>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Sun Aug 16 16:45:13 2009

import wx
import wx.grid

# begin wxGlade: extracode
# end wxGlade

class MyFrame(wx.Frame):

    def __init__(self, *args, **kwds):
        self.rows = 0
        self.fila = 0
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.button_1 = wx.Button(self, -1, "Agregar")
        self.button_2 = wx.Button(self, -1, "Quitar")
        self.grid_1 = wx.grid.Grid(self, -1, size=(1, 1))

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnAgregar, self.button_1)
        self.Bind(wx.EVT_BUTTON, self.OnQuitar, self.button_2)
        #bindeo evento
        self.grid_1.Bind(wx.grid.EVT_GRID_EDITOR_CREATED, self.OnGrid1GridEditorCreated)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("Lista editable")
        self.SetSize((400, 300))
        self.Center()
        self.grid_1.CreateGrid(1, 2)
        self.grid_1.SetRowLabelSize(0)
        self.grid_1.SetColLabelSize(30)
        self.grid_1.SetColLabelValue(0, "Nombre")
        self.grid_1.SetColLabelValue(1, "Pariente")
        # Crear la GridCellChoiceEditor con una lista en blanco. Los artículos serán
        # agregados más tarde, en tiempo de ejecución. "allowOthers" permite al usuario
        # crear nuevos elementos de selección sobre la marcha.
        tChoiceEditor = wx.grid.GridCellChoiceEditor([], allowOthers=True)
        #Asignar a los editores de la célula de la primera fila y segunda columna(fila 0).
        self.grid_1.SetCellEditor(0, 1, tChoiceEditor)
        #lista
        self.grid_1.list = ['Padre ', 'Madre','Tio/a ','Primo/a','Hermano/a', 'Abuelo/a','Vecino/a']
        #Mostrar el primer elemento de la lista en la celda ChoiceEditor
        #en este caso esta vacia, asi que no aparecera nada
        self.grid_1.SetCellValue(0, 1, self.grid_1.list[0][5])

        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3.Add(self.button_1, 0, wx.ALIGN_BOTTOM &#124;wx.ADJUST_MINSIZE, 0)
        sizer_3.Add(self.button_2, 0, wx.ALIGN_BOTTOM &#124;wx.ADJUST_MINSIZE, 0)
        sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
        sizer_2.Add(self.grid_1, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

    def OnAgregar(self, event): # wxGlade: MyFrame.
        self.grid_1.ForceRefresh()
        self.fila += 1
        #Se agrega una fila
        self.grid_1.AppendRows()
        self.grid_1.MakeCellVisible(self.rows, 0)
        self.grid_1.ForceRefresh()
        #Se agrega el comboBox
        tChoiceEditor = wx.grid.GridCellChoiceEditor([], allowOthers=True)
        self.grid_1.SetCellEditor(self.fila, 1, tChoiceEditor)
        #lista
        self.grid_1.SetCellValue(self.fila, 1, self.grid_1.list[0][5])
        self.rows += 1

    def OnQuitar(self, event): # wxGlade: MyFrame.

        if self.rows &#62; 0:
            self.grid_1.DeleteRows(self.rows)
            self.grid_1.ForceRefresh()
            self.rows -= 1
            #Cuando quito una fila tambien debo quitar self.fila
            self.fila -= 1

    def OnGrid1GridEditorCreated(self, event):
        #toma el numero de columna
        Col = event.GetCol()
        if Col == 1 :
            #Obtiene una referencia al control ComboBox subyacente
            self.comboBox = event.GetControl()
            #Cargar la lista de opciones iniciales.
            for (item) in self.grid_1.list:

                self.comboBox.Append(item)

        event.Skip()

# end of class MyFrame

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None, -1, "")
        self.SetTopWindow(frame_1)
        frame_1.Show()
        return 1

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
</h3>

</code></pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Lista editable que agrega filas]]></title>
<link>http://pymanimal.wordpress.com/2009/08/17/lista-editable/</link>
<pubDate>Mon, 17 Aug 2009 20:41:17 +0000</pubDate>
<dc:creator>dan5sanf</dc:creator>
<guid>http://pymanimal.wordpress.com/2009/08/17/lista-editable/</guid>
<description><![CDATA[Para el proyecto relaxtives me pidieron una lista editable de dos columnas que agregué filas, tipo l]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Para el proyecto <a href="http://code.google.com/p/relaxtives/">relaxtives</a> me pidieron una lista editable de dos columnas que agregué filas, tipo las que tiene wxGlade en el control ComboBox en la solapa widget.<br />
El Jefe del proyecto consiguió el código fuente a través de la página  web del proyecto wxGlade. En base a el armé este control.<br />
<img src="http://pymanimal.wordpress.com/files/2009/08/for.png?w=300" alt="for" title="for" width="300" height="240" class="aligncenter size-medium wp-image-98" /><br />
Este es el código.</p>
<pre><code>
<h3>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Sun Aug 16 16:45:13 2009

import wx
import wx.grid

# begin wxGlade: extracode
# end wxGlade

class MyFrame(wx.Frame):

    def __init__(self, *args, **kwds):
        self.rows = 0
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.button_1 = wx.Button(self, -1, "Agregar")
        self.button_2 = wx.Button(self, -1, "Quitar")
        self.grid_1 = wx.grid.Grid(self, -1, size=(1, 1))

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnAgregar, self.button_1)
        self.Bind(wx.EVT_BUTTON, self.OnQuitar, self.button_2)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("Lista editable")
        self.SetSize((400, 300))
        self.grid_1.CreateGrid(1, 2)
        self.grid_1.SetRowLabelSize(0)
        self.grid_1.SetColLabelSize(30)
        self.grid_1.SetColLabelValue(0, "Nombre")
        self.grid_1.SetColLabelValue(1, "Pariente")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3.Add(self.button_1, 0, wx.ALIGN_BOTTOM &#124;wx.ADJUST_MINSIZE, 0)
        sizer_3.Add(self.button_2, 0, wx.ALIGN_BOTTOM &#124;wx.ADJUST_MINSIZE, 0)
        sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
        sizer_2.Add(self.grid_1, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

    def OnAgregar(self, event): # wxGlade: MyFrame.

        self.grid_1.AppendRows()
        self.grid_1.MakeCellVisible(self.rows, 0)
        self.grid_1.ForceRefresh()
        self.rows += 1

    def OnQuitar(self, event): # wxGlade: MyFrame.

        if self.rows &#62; 0: #1:
            self.grid_1.DeleteRows(self.rows)
            self.rows -= 1

# end of class MyFrame

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None, -1, "")
        self.SetTopWindow(frame_1)
        frame_1.Show()
        return 1

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
</h3>

</code></pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Formulario en wxGlade]]></title>
<link>http://pymanimal.wordpress.com/2009/08/11/entrada-2/</link>
<pubDate>Tue, 11 Aug 2009 05:33:23 +0000</pubDate>
<dc:creator>dan5sanf</dc:creator>
<guid>http://pymanimal.wordpress.com/2009/08/11/entrada-2/</guid>
<description><![CDATA[Esta es mi primer práctica con wxGlade donde estoy empesando a usar sizer. Es un simple formulario, ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Esta es mi primer práctica con  wxGlade donde estoy empesando a usar sizer.<br />
<img src="http://pymanimal.wordpress.com/files/2009/08/pantallazo-1.png?w=300" alt="Pantallazo-1" title="Pantallazo-1" width="300" height="225" class="aligncenter size-medium wp-image-82" /><br />
Es un simple formulario, donde mi objetivo fué que al maximizar el frame, los TextCrtl de ingreso de datos se expandieran a lo largo y el TextCtrl de observaciones lo hiciera a  lo largo y a lo ancho. Para ello se configuro el gridSizerFormulario.AddGrowableRow(4), gridSizerFormulario.AddGrowableCol(1), gridSizerFormulario.AddGrowableCol(3), esto permite que la columna 1 , 3 y la fila 4 se agranden,  los TextCtrl para aumentar su temaño tienen que tener aliniación wx.Expand para ocupar todo el espacio disponible,  gridSizerFormulario.Add(self.textCtrlNroSocio, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0).<br />
Este es el código generado por wxGlade, esta probado en linux Debian, Ubuntu y windows xp.</p>
<pre><code>
<h3>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Fri Aug  7 11:21:21 2009

import wx

# begin wxGlade: extracode
# end wxGlade

class Frame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: Frame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.panel = wx.Panel(self, -1)
        self.stTitulo = wx.StaticText(self.panel, -1, u"Historia Clínica", style=wx.ALIGN_CENTRE)
        self.stNroSocio = wx.StaticText(self.panel, -1, "Nro Socio:")
        self.textCtrlNroSocio = wx.TextCtrl(self.panel, -1, "")
        self.stNacionalidad = wx.StaticText(self.panel, -1, "Nacionalidad:")
        self.cbNacionalidad = wx.ComboBox(self.panel, -1,u'Argentina', choices=["Argentina", "Uruguay", "Chile", "Paraguay", "Bolivia", "Venezuela", "Ecuador", "Colombia", "Honduras", "Mexico", "Estados Unidos", "Canada", "España", "Italia", "Francia", "Inglaterra", "Alemania", "Japon", "China", "India", "Rusia", "Israel","Egipto", "Etiopia"], style=wx.CB_DROPDOWN)
        self.stApellido = wx.StaticText(self.panel, -1, "Apellido:")
        self.textCtrlApellido = wx.TextCtrl(self.panel, -1, "")
        self.stRell_ = wx.StaticText(self.panel, -1, "")
        self.checkbox_1 = wx.CheckBox(self.panel, -1, "Operado")
        self.stNombre = wx.StaticText(self.panel, -1, "Nombre:")
        self.textCtrlNombre = wx.TextCtrl(self.panel, -1, "")
        self.stRell_8 = wx.StaticText(self.panel, -1, "")
        self.checkbox_2 = wx.CheckBox(self.panel, -1, "Madre")
        self.stFechNac = wx.StaticText(self.panel, -1, "Fech Nac:")
        self.datepicker = wx.DatePickerCtrl(self.panel, -1)
        self.stRell_9 = wx.StaticText(self.panel, -1, "")
        self.stObservaciones = wx.StaticText(self.panel, -1, "Observaciones:")
        self.stRell_11 = wx.StaticText(self.panel, -1, "")
        self.stRell_12 = wx.StaticText(self.panel, -1, "")
        self.stRell_13 = wx.StaticText(self.panel, -1, "")
        self.textCtrlObs = wx.TextCtrl(self.panel, -1, "", style=wx.TE_MULTILINE)
        self.btnCancelar = wx.Button(self.panel, -1, "Cancelar")
        self.btnAceptar = wx.Button(self.panel, -1, "Aceptar")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnCancelar, self.btnCancelar)
        self.Bind(wx.EVT_BUTTON, self.OnAceptar, self.btnAceptar)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: Frame.__set_properties
        self.SetTitle("Sanatorio Olivos")
        self.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.stTitulo.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.cbNacionalidad.SetSelection(-1)
        self.Center()
        self.textCtrlNroSocio.SetFocus()
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: Frame.__do_layout
        boxSizerFrame = wx.BoxSizer(wx.VERTICAL)
        boxSizerPanel = wx.BoxSizer(wx.VERTICAL)
        gridSizerBotones = wx.FlexGridSizer(0, 2, 4, 4)
        gridSizerFormulario = wx.FlexGridSizer(6, 4, 4, 4)
        boxSizerPanel.Add(self.stTitulo, 0, wx.TOP&#124;wx.ALIGN_CENTER_HORIZONTAL&#124;wx.ADJUST_MINSIZE, 10)
        gridSizerFormulario.Add(self.stNroSocio, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.textCtrlNroSocio, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stNacionalidad, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.cbNacionalidad, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stApellido, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.textCtrlApellido, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.checkbox_1, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stNombre, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.textCtrlNombre, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_8, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.checkbox_2, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stFechNac, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.datepicker, 0, wx.EXPAND&#124;wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_9, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stObservaciones, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_11, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_12, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.stRell_13, 0, wx.ADJUST_MINSIZE, 0)
        gridSizerFormulario.Add(self.textCtrlObs, 0, wx.EXPAND&#124;wx.ALIGN_BOTTOM, 0)
        gridSizerFormulario.AddGrowableRow(4)
        gridSizerFormulario.AddGrowableCol(1)
        gridSizerFormulario.AddGrowableCol(3)
        boxSizerPanel.Add(gridSizerFormulario, 1, wx.LEFT&#124;wx.RIGHT&#124;wx.TOP&#124;wx.EXPAND, 20)
        gridSizerBotones.Add(self.btnCancelar, 0, wx.ALIGN_BOTTOM, 0)
        gridSizerBotones.Add(self.btnAceptar, 0, wx.LEFT&#124;wx.ALIGN_BOTTOM, 30)
        gridSizerBotones.AddGrowableRow(0)
        gridSizerBotones.AddGrowableCol(0)
        gridSizerBotones.AddGrowableCol(1)
        boxSizerPanel.Add(gridSizerBotones, 0, wx.RIGHT&#124;wx.TOP&#124;wx.BOTTOM&#124;wx.ALIGN_RIGHT, 20)
        self.panel.SetSizer(boxSizerPanel)
        boxSizerFrame.Add(self.panel, 1, wx.EXPAND, 0)
        self.SetSizer(boxSizerFrame)
        boxSizerFrame.Fit(self)
        self.Layout()
        # end wxGlade

    def OnCancelar(self, event): # wxGlade: Frame.
        self.Close()
        event.Skip()

    def OnAceptar(self, event): # wxGlade: Frame.
        ingresoNroSocio = self.textCtrlNroSocio.GetValue()
        ingresoApellido = self.textCtrlApellido.GetValue()
        ingresoNombre = self.textCtrlNombre.GetValue()
        ingresoFechNac = self.datepicker.GetValue()
        #formato de fecha= año-mes-día, Ej: 1961/01/05
        ingresoFechNac = ('%4d/%02d/%02d' %(ingresoFechNac.GetYear(), ingresoFechNac.GetMonth()+1,ingresoFechNac.GetDay()))
        ingresoNacionalidad = self.cbNacionalidad.GetValue()
        ingresoOperado = self.checkbox_1.GetValue()
        if ingresoOperado == True:
            operado = 'Si'
        else:
            operado = 'No'
        ingresoMadre = self.checkbox_2.GetValue()
        if ingresoMadre == True:
            madre = 'Si'
        else:
            madre = 'No'
        ingresoObs = self.textCtrlObs.GetValue()
        datos = u'''
        Nro Socio: %s
        Apellido: %s
        Nombre: %s
        Fecha Nac: %s
        Nacionalidad: %s
        Operado: %s
        Madre: %s
        Observaciones: %s
        ''' %(ingresoNroSocio,ingresoApellido,ingresoNombre,ingresoFechNac,ingresoNacionalidad, operado, madre, ingresoObs)
        dlg = wx.MessageDialog(self, datos, u'Confirmación de Envio',wx.OK &#124; wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()
        event.Skip()

# end of class Frame

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame = Frame(None, -1, "")
        self.SetTopWindow(frame)
        frame.Show()
        return 1

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
</h3>
</pre>
<p></code></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Determining button up/down times in wxPython]]></title>
<link>http://crankycode.wordpress.com/2009/07/03/determining-button-updown-times-in-wxpython/</link>
<pubDate>Fri, 03 Jul 2009 20:59:25 +0000</pubDate>
<dc:creator>John</dc:creator>
<guid>http://crankycode.wordpress.com/2009/07/03/determining-button-updown-times-in-wxpython/</guid>
<description><![CDATA[I recently encountered a need to be able to determine how long a user held down a button on a GUI di]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I recently encountered a need to be able to determine how long a user held down a button on a GUI dialog in order to command a proportional amount of movement in a mechanism. In other words, the longer the button was down, the longer the mechanism would be commanded to move.</p>
<p>It turns out that this is relatively easy to do with wxPython. Basically one merely needs to bind the mouse events wx.EVT_LEFT_DOWN and wx.EVT_LEFT_UP events to the button of interest. When the left mouse button is pressed the wx.EVT_LEFT_DOWN event is generated, and when it is released a wx.EVT_LEFT_UP event occurs. By binding handlers to these events one can use them to determine when a button was selected and how long it was held down by the user.</p>
<p>There are two ways to bind the mouse button events. The first uses the &#8220;old&#8221; style and looks like this:</p>
<p><code>wx.EVT_LEFT_DOWN(self.button1, self.OnBtn1Down)</code></p>
<p>and the second form using the &#8220;new&#8221; style with the Bind method looks like this:</p>
<p><code>self.button1.Bind(wx.EVT_LEFT_DOWN, self.OnBtn1Down)</code></p>
<p>There are also corresponding handlers for the wx.EVT_LEFT_UP event.</p>
<p>In the button up/down event handlers the last statement must be event.Skip(), otherwise the button event will not be passed on  to the &#8220;real&#8221; button event handler.</p>
<p>I&#8217;ve provided two examples below. The first is frame-based and uses a textbox widget to display the timing data for each button. The second use a modal dialog box and text control widgets to display the click data.</p>
<p>Both versions display a running average &#8220;down-time&#8221; for button 1, along with a click total. For buttons 2 and 3 just the down-time is displayed. The clear button, as one might surmise, clears out all previous data.</p>
<p><strong>Frame and Panel Version</strong></p>
<pre class="brush: python;">
&quot;&quot;&quot; wxPython Button timing example

    Uses the wx.EVT_LEFT_DOWN and wx.EVT_LEFT_UP events to determine how long
    a button has been held down by the user.

    The up/down events are bound to the buttons, and the actual button event
    is processed after the button is released. It is important to note that
    the up/down handlers MUST call event.Skip() in order to pass the events
    along to the &quot;real&quot; button event handlers.

    Button 1 generates a cumulative click count and an average hold-down time.
    Multiple clicking has shown that the average down time is around 70 mS
    unless the user is really quick, in which case it can drop to around 55 mS.

    Buttons 2 and 3 simply display the hold-down time.

    The Clear button clears the text display and resets the count and average
    values for button 1.

    To execute:

        python buttontime.py

    29 June 2009 - jmh
&quot;&quot;&quot;

import wx
import time

class ButtonPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        self.btn1downtime = 0
        self.btn2downtime = 0
        self.btn3downtime = 0

        self.btn1_time = 0
        self.btn2_time = 0
        self.btn3_time = 0

        self.btn1_clks = 0
        self.btn1_tot  = 0

        self.idBtn1 = wx.NewId()
        self.idBtn2 = wx.NewId()
        self.idBtn3 = wx.NewId()
        self.idBtn4 = wx.NewId()
        self.idBtn5 = wx.NewId()

        topsizer     = wx.BoxSizer( wx.HORIZONTAL )
        menusizer    = wx.BoxSizer( wx.VERTICAL )
        contentsizer = wx.BoxSizer( wx.VERTICAL )

        self.textbox = wx.TextCtrl(self, -1, &quot;&quot;,
            wx.DefaultPosition, wx.DefaultSize,
            wx.TE_MULTILINE)

        self.textbox.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))

        self.button1 = wx.Button(self, self.idBtn1, &quot;Button 1&quot;)
        self.button2 = wx.Button(self, self.idBtn2, &quot;Button 2&quot;)
        self.button3 = wx.Button(self, self.idBtn3, &quot;Button 3&quot;)
        self.button4 = wx.Button(self, self.idBtn4, &quot;Quit&quot;)
        self.button5 = wx.Button(self, self.idBtn5, &quot;Clear&quot;)

        self.button1.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.button2.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.button3.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.button4.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.button5.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))

        wx.EVT_LEFT_DOWN(self.button1, self.OnBtn1Down)
        wx.EVT_LEFT_UP(self.button1, self.OnBtn1Up)

        wx.EVT_LEFT_DOWN(self.button2, self.OnBtn2Down)
        wx.EVT_LEFT_UP(self.button2, self.OnBtn2Up)

        wx.EVT_LEFT_DOWN(self.button3, self.OnBtn3Down)
        wx.EVT_LEFT_UP(self.button3, self.OnBtn3Up)

        wx.EVT_BUTTON(self, self.idBtn1, self.OnBtn1)
        wx.EVT_BUTTON(self, self.idBtn2, self.OnBtn2)
        wx.EVT_BUTTON(self, self.idBtn3, self.OnBtn3)
        wx.EVT_BUTTON(self, self.idBtn4, self.OnBtn4)
        wx.EVT_BUTTON(self, self.idBtn5, self.OnBtn5)

        contentsizer.Add(self.textbox, 1, wx.EXPAND)

        menusizer.Add(self.button1, 1, wx.EXPAND)
        menusizer.Add(self.button2, 1, wx.EXPAND)
        menusizer.Add(self.button3, 1, wx.EXPAND)
        menusizer.Add(self.button4, 1, wx.EXPAND)
        menusizer.Add(self.button5, 1, wx.EXPAND)

        topsizer.Add(menusizer, 0)
        topsizer.Add(contentsizer, 1, wx.EXPAND)

        self.SetSizer(topsizer)

    #---------------------------------------------------------------------------
    # Mouse button event handlers
    #---------------------------------------------------------------------------
    def OnBtn1Down(self, event):
        self.btn1_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnBtn1Up(self, event):
        self.btn1_uptime = time.time()
        self.btn1_time = self.btn1_uptime - self.btn1_downtime
        self.btn1_clks += 1
        self.btn1_tot += self.btn1_time
        event.Skip()    # REQUIRED!

    def OnBtn2Down(self, event):
        self.btn2_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnBtn2Up(self, event):
        self.btn2_uptime = time.time()
        self.btn2_time = self.btn2_uptime - self.btn2_downtime
        event.Skip()    # REQUIRED!

    def OnBtn3Down(self, event):
        self.btn3_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnBtn3Up(self, event):
        self.btn3_uptime = time.time()
        self.btn3_time = self.btn3_uptime - self.btn3_downtime
        event.Skip()    # REQUIRED!

    #---------------------------------------------------------------------------
    # Button widget event handlers
    #---------------------------------------------------------------------------
    def OnBtn1(self, event):
        self.textbox.AppendText(&quot;Btn1: %3.3f, clicks: %d, avg: %3.3f\n&quot; % \
                                (self.btn1_time,
                                 self.btn1_clks,
                                (self.btn1_tot/self.btn1_clks)))

    def OnBtn2(self, event):
        self.textbox.AppendText(&quot;Btn2: %3.3f\n&quot; % self.btn2_time)

    def OnBtn3(self, event):
        self.textbox.AppendText(&quot;Btn3: %3.3f\n&quot; % self.btn3_time)

    def OnBtn4(self, event):
        self.GetParent().Close(True)

    def OnBtn5(self, event):
        self.btn1_time = 0
        self.btn2_time = 0
        self.btn3_time = 0

        self.btn1_clks = 0
        self.btn1_tot  = 0

        self.textbox.Clear()

#-------------------------------------------------------------------------------
# Launch
#-------------------------------------------------------------------------------
app     = wx.PySimpleApp(0)
frame   = wx.Frame(None, -1, &quot;Timed Buttons&quot;)

ButtonPanel(frame)

frame.Show(True)
frame.SetSize(wx.Size(800, 600))
frame.Move(wx.Point(50,50))

app.MainLoop()
</pre>
<p><strong>wx.Dialog Version</strong></p>
<p>Note that this version is in two parts: buttondlg.py and dlgTimedButtons.py. The Boa Constructor tool was used to create the dialog skeleton, and the rest was filled in afterwards. Use the &#8220;Evts&#8221; tab in Boa&#8217;s Inspector panel to add the mouse events to a particular button.</p>
<pre class="brush: python;">
# buttondlg.py
#
# Creates frame with menu and status bar for use with dlgTimedButtons
#
# 3 July 2009 - jmh

import wx

import dlgTimedButtons

idShowDlg = wx.NewId()
idQuit    = wx.NewId()

class DlgTimedButton(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        menubar = wx.MenuBar()
        mainmenu = wx.Menu()
        mainmenu.Append(idShowDlg, 'Dialog', 'Timed buttons dialog')
        mainmenu.Append(idQuit, 'Quit', 'Quit application')

        self.Bind(wx.EVT_MENU, self.OnShowDlg, id=idShowDlg)
        self.Bind(wx.EVT_MENU, self.OnQuit, id=idQuit)

        menubar.Append(mainmenu, 'Main')
        self.SetMenuBar(menubar)

        self.statusbar = self.CreateStatusBar()

        self.Centre()
        self.Show(True)

    def OnShowDlg(self, event):
        dlg = dlgTimedButtons.dlgTimedButtons(self)
        dlg.ShowModal()

    def OnQuit(self, event):
        self.Close()

#-------------------------------------------------------------------------------
# Launch
#-------------------------------------------------------------------------------
app = wx.App()
DlgTimedButton(None, -1, 'Timed Button Dialog Example')
app.MainLoop()
</pre>
<p>and here is the actual dialog with the timed button goodness:</p>
<pre class="brush: python;">
#Boa:Dialog:dlgTimedButtons
#
# Timed button modal dialog example
# 3 July 2009 - jmh
# initially created with Boa Constructor

import wx
import time

def create(parent):
    return dlgTimedButtons(parent)

[wxID_DLGTIMEDBUTTONS, wxID_DLGTIMEDBUTTONSBTNCLEAR,
 wxID_DLGTIMEDBUTTONSBTNQUIT, wxID_DLGTIMEDBUTTONSBUTTON1,
 wxID_DLGTIMEDBUTTONSBUTTON2, wxID_DLGTIMEDBUTTONSBUTTON3,
 wxID_DLGTIMEDBUTTONSSTATICTEXT1, wxID_DLGTIMEDBUTTONSSTATICTEXT2,
 wxID_DLGTIMEDBUTTONSSTATICTEXT3, wxID_DLGTIMEDBUTTONSTXTBTN1CLICKS,
 wxID_DLGTIMEDBUTTONSTXTBTNTIME1, wxID_DLGTIMEDBUTTONSTXTBTNTIME1AVG,
 wxID_DLGTIMEDBUTTONSTXTBTNTIME2, wxID_DLGTIMEDBUTTONSTXTBTNTIME3,
] = [wx.NewId() for _init_ctrls in range(14)]

class dlgTimedButtons(wx.Dialog):
    def __init__(self, parent):
        self.btn1downtime = 0
        self.btn2downtime = 0
        self.btn3downtime = 0

        self.btn1_time = 0
        self.btn2_time = 0
        self.btn3_time = 0

        self.btn1_clks = 0
        self.btn1_tot  = 0

        self._init_ctrls(parent)
        self.ClrDisplay()

    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Dialog.__init__(self, id=wxID_DLGTIMEDBUTTONS,
              name='dlgTimedButtons', parent=prnt, pos=wx.Point(477, 295),
              size=wx.Size(353, 201), style=wx.DEFAULT_DIALOG_STYLE,
              title='Timed Buttons')
        self.SetClientSize(wx.Size(345, 174))

        self.button1 = wx.Button(id=wxID_DLGTIMEDBUTTONSBUTTON1,
              label='Button 1', name='button1', parent=self, pos=wx.Point(16,
              24), size=wx.Size(75, 23), style=0)
        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
              id=wxID_DLGTIMEDBUTTONSBUTTON1)
        self.button1.Bind(wx.EVT_LEFT_UP, self.OnButton1LeftUp)
        self.button1.Bind(wx.EVT_LEFT_DOWN, self.OnButton1LeftDown)

        self.button2 = wx.Button(id=wxID_DLGTIMEDBUTTONSBUTTON2,
              label='Button 2', name='button2', parent=self, pos=wx.Point(16,
              72), size=wx.Size(75, 23), style=0)
        self.button2.Bind(wx.EVT_BUTTON, self.OnButton2Button,
              id=wxID_DLGTIMEDBUTTONSBUTTON2)
        self.button2.Bind(wx.EVT_LEFT_UP, self.OnButton2LeftUp)
        self.button2.Bind(wx.EVT_LEFT_DOWN, self.OnButton2LeftDown)

        self.button3 = wx.Button(id=wxID_DLGTIMEDBUTTONSBUTTON3,
              label='Button 3', name='button3', parent=self, pos=wx.Point(16,
              96), size=wx.Size(75, 23), style=0)
        self.button3.Bind(wx.EVT_BUTTON, self.OnButton3Button,
              id=wxID_DLGTIMEDBUTTONSBUTTON3)
        self.button3.Bind(wx.EVT_LEFT_UP, self.OnButton3LeftUp)
        self.button3.Bind(wx.EVT_LEFT_DOWN, self.OnButton3LeftDown)

        self.btnQuit = wx.Button(id=wxID_DLGTIMEDBUTTONSBTNQUIT, label='Close',
              name='btnQuit', parent=self, pos=wx.Point(16, 144),
              size=wx.Size(75, 23), style=0)
        self.btnQuit.Bind(wx.EVT_BUTTON, self.OnBtnQuitButton,
              id=wxID_DLGTIMEDBUTTONSBTNQUIT)

        self.txtBtnTime1 = wx.TextCtrl(id=wxID_DLGTIMEDBUTTONSTXTBTNTIME1,
              name='txtBtnTime1', parent=self, pos=wx.Point(112, 24),
              size=wx.Size(100, 21), style=0, value='')
        self.txtBtnTime1.SetEditable(False)

        self.txtBtnTime2 = wx.TextCtrl(id=wxID_DLGTIMEDBUTTONSTXTBTNTIME2,
              name='txtBtnTime2', parent=self, pos=wx.Point(112, 72),
              size=wx.Size(100, 21), style=0, value='')
        self.txtBtnTime2.SetEditable(False)

        self.txtBtnTime3 = wx.TextCtrl(id=wxID_DLGTIMEDBUTTONSTXTBTNTIME3,
              name='txtBtnTime3', parent=self, pos=wx.Point(112, 96),
              size=wx.Size(100, 21), style=0, value='')
        self.txtBtnTime3.SetEditable(False)

        self.txtBtnTime1Avg = wx.TextCtrl(id=wxID_DLGTIMEDBUTTONSTXTBTNTIME1AVG,
              name='txtBtnTime1Avg', parent=self, pos=wx.Point(272, 24),
              size=wx.Size(64, 21), style=0, value='')
        self.txtBtnTime1Avg.SetEditable(False)

        self.staticText1 = wx.StaticText(id=wxID_DLGTIMEDBUTTONSSTATICTEXT1,
              label='Times', name='staticText1', parent=self, pos=wx.Point(144,
              48), size=wx.Size(40, 16), style=0)

        self.staticText2 = wx.StaticText(id=wxID_DLGTIMEDBUTTONSSTATICTEXT2,
              label='Average', name='staticText2', parent=self,
              pos=wx.Point(224, 32), size=wx.Size(41, 13), style=0)

        self.txtBtn1Clicks = wx.TextCtrl(id=wxID_DLGTIMEDBUTTONSTXTBTN1CLICKS,
              name='txtBtn1Clicks', parent=self, pos=wx.Point(272, 48),
              size=wx.Size(64, 21), style=0, value='')
        self.txtBtn1Clicks.SetEditable(False)

        self.staticText3 = wx.StaticText(id=wxID_DLGTIMEDBUTTONSSTATICTEXT3,
              label='Clicks', name='staticText3', parent=self, pos=wx.Point(240,
              56), size=wx.Size(26, 13), style=0)

        self.btnClear = wx.Button(id=wxID_DLGTIMEDBUTTONSBTNCLEAR,
              label='Clear', name='btnClear', parent=self, pos=wx.Point(160,
              144), size=wx.Size(51, 23), style=0)
        self.btnClear.Bind(wx.EVT_BUTTON, self.OnBtnClearButton,
              id=wxID_DLGTIMEDBUTTONSBTNCLEAR)

        self.txtBtnTime1.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, 'Arial'))
        self.txtBtnTime2.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, 'Arial'))
        self.txtBtnTime3.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, 'Arial'))
        self.txtBtnTime1Avg.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, 'Arial'))
        self.txtBtn1Clicks.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, 'Arial'))

    def ClrDisplay(self):
        self.txtBtnTime1.SetValue(&quot;0.0&quot;)
        self.txtBtnTime2.SetValue(&quot;0.0&quot;)
        self.txtBtnTime3.SetValue(&quot;0.0&quot;)

        self.txtBtnTime1Avg.SetValue(&quot;0&quot;)
        self.txtBtn1Clicks.SetValue(&quot;0.0&quot;)

    def OnButton1LeftUp(self, event):
        self.btn1_uptime = time.time()
        self.btn1_time = self.btn1_uptime - self.btn1_downtime
        self.btn1_clks += 1
        self.btn1_tot += self.btn1_time
        event.Skip()    # REQUIRED!

    def OnButton1LeftDown(self, event):
        self.btn1_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnButton2LeftUp(self, event):
        self.btn2_uptime = time.time()
        self.btn2_time = self.btn2_uptime - self.btn2_downtime
        event.Skip()    # REQUIRED!

    def OnButton2LeftDown(self, event):
        self.btn2_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnButton3LeftUp(self, event):
        self.btn3_uptime = time.time()
        self.btn3_time = self.btn3_uptime - self.btn3_downtime
        event.Skip()    # REQUIRED!

    def OnButton3LeftDown(self, event):
        self.btn3_downtime = time.time()
        event.Skip()    # REQUIRED!

    def OnButton1Button(self, event):
        self.txtBtnTime1.SetValue(&quot;%3.3f&quot; % self.btn1_time)
        self.txtBtnTime1Avg.SetValue(&quot;%3.3f&quot; % (self.btn1_tot/self.btn1_clks))
        self.txtBtn1Clicks.SetValue(str(self.btn1_clks))

    def OnButton2Button(self, event):
        self.txtBtnTime2.SetValue(&quot;%3.3f&quot; % self.btn2_time)

    def OnButton3Button(self, event):
        self.txtBtnTime3.SetValue(&quot;%3.3f&quot; % self.btn3_time)

    def OnBtnQuitButton(self, event):
        self.Destroy()

    def OnBtnClearButton(self, event):
        self.btn1_time = 0
        self.btn2_time = 0
        self.btn3_time = 0
        self.btn1_clks = 0
        self.btn1_tot  = 0
        self.ClrDisplay()
</pre>
<p>And that&#8217;s it. It&#8217;s just that easy. Once the time interval between the down and up events has been captured it can be put to use in various interesting ways.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Android Game Sounds]]></title>
<link>http://mobilebytes.wordpress.com/2009/07/03/android-game-sounds/</link>
<pubDate>Fri, 03 Jul 2009 08:28:35 +0000</pubDate>
<dc:creator>sharemefg</dc:creator>
<guid>http://mobilebytes.wordpress.com/2009/07/03/android-game-sounds/</guid>
<description><![CDATA[Remember in 2007 Sonivox donated some game sound technology to OHA and Android? Some examples of Jet]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/1FJHYqE0RDg&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/1FJHYqE0RDg&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span><br />
Remember in 2007 Sonivox donated some game sound technology to OHA and Android? Some examples of JetCreator and JetCreator to create the MIDI sequences for game music are in the Git repo, the sub-folder is:</p>
<p>external/sonivox/jettools</p>
<p>You need Python Version 2.5.4 and wxPython Version 2.8.7.1 installed or versions higher than that. To run the samples copy that sub-folder to your Home/opt directory and cd to JetCreator directory to run JetCreator.py. I do not know any Linux tools that create the JET asset archives files other than jetCreator.py. The <a href="http://developer.android.com/guide/topics/media/jet/jetcreator_manual.html">JetCreator manual is here</a>. You wil not be able to play back soudn sin JetCreator in Liux but have to use the emulator. The code to use the JetPlaer class looks like this <a href="http://developer.android.com/guide/topics/media/">from the media instructions</a>:</p>
<pre class="brush: java;">
&lt;pre&gt;JetPlayer myJet = JetPlayer.getJetPlayer();
myJet.loadJetFile(&quot;/sdcard/level1.jet&quot;);
byte segmentId = 0;

// queue segment 5, repeat once, use General MIDI, transpose by -1 octave
myJet.queueJetSegment(5, -1, 1, -1, 0, segmentId++);
// queue segment 2
myJet.queueJetSegment(2, -1, 0, 0, 0, segmentId++);

myJet.play();&lt;/pre&gt;
</pre>
<p>The JetBoy example is in the reop sub-folder of:</p>
<p>development/samples</p>
<p>You can access JET files form two locations. Ones, as a raw resource in your APK file so in other words it would be in your assets project sub-folder. Second, as a JET file in on the SDCard. You will want to look at the jetBoy sample code as there is&#160; some beginning code to adjust animation ot speed of the JET MIDI music playing per FPS.Iam referrrign you to the reop rather than the SDK as ther obviously will be changes as they ready Android SDK 2.0.</p>
<p>Obviously, we than can apply this to non-game such as playing sounds in the HomeScreen application.</p>
<div class="zemanta-pixie" style="margin-top:10px;height:15px;"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/52ab8d09-60d5-4e33-95e2-1f49b05012dc/"><img class="zemanta-pixie-img" style="border:medium none;float:right;" src="http://img.zemanta.com/reblog_e.png?x-id=52ab8d09-60d5-4e33-95e2-1f49b05012dc" alt="Reblog this post [with Zemanta]"></a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[newNowarez_6.29.09]]></title>
<link>http://doubleunderscore.wordpress.com/2009/06/30/newnowarez_6-29-09/</link>
<pubDate>Tue, 30 Jun 2009 05:28:34 +0000</pubDate>
<dc:creator>Nicholas O&#039;Brien</dc:creator>
<guid>http://doubleunderscore.wordpress.com/2009/06/30/newnowarez_6-29-09/</guid>
<description><![CDATA[]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/ZW19nzGy610&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/ZW19nzGy610&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[No_warez Sample]]></title>
<link>http://doubleunderscore.wordpress.com/2009/06/27/no_warez-sample/</link>
<pubDate>Sat, 27 Jun 2009 18:10:16 +0000</pubDate>
<dc:creator>Nicholas O&#039;Brien</dc:creator>
<guid>http://doubleunderscore.wordpress.com/2009/06/27/no_warez-sample/</guid>
<description><![CDATA[After much tinkering, and switching from openGL (which I don&#8217;t want to abandon yet) to wxPytho]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img src="http://doubleunderscore.wordpress.com/files/2009/06/picture-21.png" alt="Picture 2" title="Picture 2" width="233" height="234" class="aligncenter size-full wp-image-494" /></p>
<p>
After much tinkering, and switching from openGL (which I don&#8217;t want to abandon yet) to <a href="http://wxpython.org/">wxPython</a>, I came to this simple mock up. I hope to advance from this in the near future, but I think maybe my eyes need a bit of a rest.</p>
<p>
<strong>UPDATE ::</strong></p>
<p>
<span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/MwMwq2mWOmU&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/MwMwq2mWOmU&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span></p>
<p>
Mark I put together this mock-up just a moment ago, making things inspiring.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[wxPython]]></title>
<link>http://engraver.wordpress.com/2009/03/29/wxpython/</link>
<pubDate>Sun, 29 Mar 2009 16:30:23 +0000</pubDate>
<dc:creator>Engraver</dc:creator>
<guid>http://engraver.wordpress.com/2009/03/29/wxpython/</guid>
<description><![CDATA[Уже несколько дней разбираюсь с Python и не могу нарадоваться гибкости и кросплатфоменности языка. П]]></description>
<content:encoded><![CDATA[Уже несколько дней разбираюсь с Python и не могу нарадоваться гибкости и кросплатфоменности языка. П]]></content:encoded>
</item>
<item>
<title><![CDATA[Tumblr: pantalla de login]]></title>
<link>http://wxpython.wordpress.com/2009/03/04/tumblr-pantalla-de-login/</link>
<pubDate>Wed, 04 Mar 2009 19:01:14 +0000</pubDate>
<dc:creator>wxpython</dc:creator>
<guid>http://wxpython.wordpress.com/2009/03/04/tumblr-pantalla-de-login/</guid>
<description><![CDATA[Tengo la intencion de hacer screencast del desarrollo de las pantallas del cliente de tumblr, pero n]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;"><img class="alignleft" title="tumblr login" src="http://farm4.static.flickr.com/3355/3329088572_168167e46e_o.png" alt="" width="116" height="161" />Tengo la intencion de hacer screencast del desarrollo de las pantallas del cliente de tumblr, pero no he encontrado algun programa gratuito o no logro hacer funcionar vlc.</p>
<p style="text-align:justify;">Wxglade permite el diseño rapido de interfaces para el usuario, la estructura de una interfaz debe ser frame/panel/dialog/etc despues de cualquiera de estos se debe colocar un sizer para acomodar los widgets a utilizar.</p>
<p><!--more--></p>
<p style="text-align:justify;">En el caso de la pantalla del login se uso un frame para generar la ventana que contiene un sizer (sizer_1), en este sizer se agrega un slot para colocar la etiqueta l_tumblr que muestra el titulo &#8220;Tumblr&#8221; y el otro slot se coloca un panel . En la pagina web de tumblr todos los elementos se encuentran dentro de un &#8220;marco&#8221; blanco, para hacer algo similar se agrega un panel con su respectivo sizer y colocar ahora si el panel que contendra los widgets del login.</p>
<p style="text-align:justify;"><img class="alignright" title="tree login" src="http://farm4.static.flickr.com/3343/3329088534_72c8a7575c_o.png" alt="" width="215" height="300" />En la panel (panel_login) siguiendo la misma secuencia se agrega un sizer (sizer_login) y por cada widget que agreguemos se debe insertar en su respectivo slot. Entonces el sizer_login contendra 7 slots en el orden para los widgets como: l_login, l_mail, tc_mail, l_password, tc_password, spacer, b_login. Ya para terminar basta con generar el codigo, para esto en la ventana del arbol de widgets se debe seleccionar la raiz (Application) e ir a la ventana de propiedades en la parte inferior se debe colocar el path del archivo donde se va a generar el codigo, desde el menu-&#62;file se puede generar.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Will Going Psycho Help?]]></title>
<link>http://megamicrobase.wordpress.com/2009/02/17/will-going-psycho-help/</link>
<pubDate>Tue, 17 Feb 2009 21:00:51 +0000</pubDate>
<dc:creator>willdampier</dc:creator>
<guid>http://megamicrobase.wordpress.com/2009/02/17/will-going-psycho-help/</guid>
<description><![CDATA[Hi all, I&#8217;ve run into a blog post the other day that used the Psycho module to accelerate thei]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi all,</p>
<p>I&#8217;ve run into a <a href="http://paddy3118.blogspot.com/2009/02/comparison-of-python-solutions-to.html">blog post</a> the other day that used the Psycho module to accelerate their Python code with trivial changes to the source code.  These are described well in the <a href="http://psyco.sourceforge.net/psycoguide/node8.html">Pyscho Documentation</a>.</p>
<p>I&#8217;ve been having some trouble with the AutoComplete function which I talk about <a href="http://megamicrobase.wordpress.com/2009/01/16/adventures-in-wxpython-autocompleting/">here</a>.  When I have large ontologies it takes ~1 second to sort all of the terms as each letter is typed.  While this may not seem like a long time, try counting to 5-Mississippi while typing &#8220;Blood&#8221; and you&#8217;ll see how frustrating this could be.  Profiling has revealed that the sorting function takes up a large portion of that time.  Even though it only takes 0.001 seconds per call, it needs ~5-10K calls per letter.  A 10% speed-up would save a lot of time, and Pyscho claims 2-100x speed-up.</p>
<p>If I have a free hour or two I&#8217;m going to try out Pyscho and see if it can help out a little.  If anyone has suggestions, like will Pyscho work for wxPython, please leave them in the comments.</p>
<p>-Will</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Dependencies you can Depend on]]></title>
<link>http://megamicrobase.wordpress.com/2009/02/17/dependencies-you-can-depend-on/</link>
<pubDate>Tue, 17 Feb 2009 06:27:41 +0000</pubDate>
<dc:creator>willdampier</dc:creator>
<guid>http://megamicrobase.wordpress.com/2009/02/17/dependencies-you-can-depend-on/</guid>
<description><![CDATA[Hi all, Sadly nobody gets to program in a bubble.  Everyone has deadlines, legacy code, legacy compu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi all,</p>
<p>Sadly nobody gets to program in a bubble.  Everyone has deadlines, legacy code, legacy computers, legacy programmers, etc.  We also don&#8217;t have unlimited time to &#8220;re-invent the wheel&#8221; at each opportunity.  Assumming you&#8217;re doing an open source project (much like this one), you can incorporate other people&#8217;s tools into your own code.</p>
<p>If I need to fix some automatically generated XML or HTML, instead of writing my own code, I can just import <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>.  If I need to render information into HTML or an e-mail, instead of writing my own code, I can just use <a href="http://jinja.pocoo.org/2/">jinja templates</a>.  If I need to make a GUI, instead of complaining about how people have forgotten (or never learned) how to use command line, I can just use <a href="http://www.wxpython.org/">wxPython</a>.</p>
<p>I&#8217;m new to the development world.  I&#8217;m usually the only user of my code, and it only needs to run on my computer.  When I submit code for publication I do a cursory check to make sure it runs on another computer, but ultimately I leave it up to the readers to figure out the dependencies.  However, this project is different.  I need to ensure that the code runs on any computer with only a minor amount of fiddling &#8230; especially since this may be used by technically unsavy users.</p>
<p>After plenty of googling and some half-brained ideas to use command-line calls to easy_install I found that setuptools allows a programmer to specify the dependencies.  Whenever I used easy_install I noticed that it would install dependencies, I just didn&#8217;t make the obvious leap that I could also define them in my own setup file.</p>
<p>In the next post I&#8217;ll discuss some of my trials and tribulations on ensuring that all of my code is packaged correctly.</p>
<p>-Will</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Python no windows: console, janelas e serviço]]></title>
<link>http://ricobl.wordpress.com/2009/02/13/python-no-windows-console-janelas-e-servico/</link>
<pubDate>Sat, 14 Feb 2009 00:39:55 +0000</pubDate>
<dc:creator>Rico</dc:creator>
<guid>http://ricobl.wordpress.com/2009/02/13/python-no-windows-console-janelas-e-servico/</guid>
<description><![CDATA[Devem fazer uns 10 anos que trabalho com web, não tenho do que reclamar, gosto muito e pretendo cont]]></description>
<content:encoded><![CDATA[Devem fazer uns 10 anos que trabalho com web, não tenho do que reclamar, gosto muito e pretendo cont]]></content:encoded>
</item>
<item>
<title><![CDATA[Instalando wxpython]]></title>
<link>http://wxpython.wordpress.com/2009/02/12/instalando-wxpython/</link>
<pubDate>Thu, 12 Feb 2009 05:02:52 +0000</pubDate>
<dc:creator>wxpython</dc:creator>
<guid>http://wxpython.wordpress.com/2009/02/12/instalando-wxpython/</guid>
<description><![CDATA[wxpython Existen diferentes metodos y nombres de paquetes a instalar de acuerdo a la plataforma de d]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div class="wp-caption alignleft" style="width: 149px"><img title="wxpython" src="http://upload.wikimedia.org/wikipedia/commons/c/c0/WxPython-logo.png" alt="wxpython" width="139" height="89" /><p class="wp-caption-text">wxpython</p></div>
<p style="text-align:justify;">Existen diferentes metodos y nombres de paquetes a instalar de acuerdo a la plataforma de desarrollo a usar, lo mas recomendable es usar un sistema linux y despues probar la aplicacion en otras.</p>
<p><!--more--></p>
<p style="text-align:justify;">Los paquetes necesarios son:</p>
<ul style="text-align:justify;">
<li><a href="http://www.python.org/download/">python</a></li>
<li><a href="http://downloads.sourceforge.net/wxpython/wxPython2.8-osx-ansi-2.8.9.1-universal-py2.6.dmg">wxpython</a></li>
<li><a href="http://downloads.sourceforge.net/wxpython/wxPython2.8-osx-docs-demos-2.8.9.1-universal-py2.6.dmg">wxpython docs/demos</a> ( opcional , pero muy util )</li>
</ul>
<p style="text-align:justify;">El sistema que uso es osx, para iniciar basta con descargar los paquetes (dmg)  e instalarlos como cualquier otra aplicacion. En el caso de python ya viene por default en osx ( leopard ), en este momento tengo la 2.5 pero se puede trabajar con la 2.6 . En el caso de sistemas linux se debe utilizar</p>
<pre class="code" style="padding-left:30px;">apt-get install wxpython-version</pre>
<pre class="code" style="padding-left:30px;">yum install wxpython-version</pre>
<p style="text-align:justify;">Tambien es opcional la instalacion de <a href="http://wxglade.sourceforge.net/">wxglade</a>, sirve para crear la interfaz grafica mas rapido. Solo hay que  <a href="http://downloads.sourceforge.net/wxglade/wxGlade-0.6.3.tar.gz?modtime=1201950639&#38;big_mirror=0">descargarlo</a> y  &#8220;desempaquetar&#8221;.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Adventures in wxPython AutoCompleting]]></title>
<link>http://megamicrobase.wordpress.com/2009/01/16/adventures-in-wxpython-autocompleting/</link>
<pubDate>Fri, 16 Jan 2009 05:30:35 +0000</pubDate>
<dc:creator>willdampier</dc:creator>
<guid>http://megamicrobase.wordpress.com/2009/01/16/adventures-in-wxpython-autocompleting/</guid>
<description><![CDATA[Hi all, Today’s project was to finish up loose ends on the wxPython Annotation GUI.  There are two t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi all,</p>
<p><span>Today’s project was to finish up loose ends on the wxPython Annotation GUI.<span>  </span>There are two things left that prevent me from annotating the GEO database with ontologies.<span>  </span>I need to be able to search the ontology tree with a search term while annotating (in case the suggestions provided are incorrect or unhelpful) and I need a way to auto-download all of the GSE/GSM records that result from a search engine.<span>  </span>I decided to work on the former problem today.</span></p>
<p><span>When I parse the ontology file I gather the official names and synonyms into a dictionary for easy retrieval of the OntolgyRecord by name.<span>  </span>This may get me into trouble if there are two different ontology records with overlapping synonyms, but I haven’t encountered this yet and I’ll deal with it then.<span>  </span>I want a way to search these terms with an AutoCompleting feature.<span>  </span>After doing some googling I came across this <a href="http://lists.wxwidgets.org/pipermail/wxpython-users/2006-June/052496.html">post</a>.<span>  </span>The authors wrote a subclass of wxTextCtlr with an associated wxListCtrl.<span>  </span>I included this file at <a href="http://code.google.com/p/megamicrobase/source/detail?r=65">Revision 65</a> in svn/trunk/ DMtools/wxAutoComplete.py.<span>  </span></span></p>
<p><span>The control will auto-complete your entry by scrolling to the relevant entry in the listctrl.<span>  </span>However, the code as downloaded was insufficient for my needs.</span></p>
<p><span><span>1.<span>      </span></span></span><span>It would scroll to the first instance where it could auto-complete.<span>  </span>If the input list was unsorted it would only show one helpful suggestion.</span></p>
<p><span><span>2.<span>      </span></span></span><span>It couldn’t deal with inputs that had spaces.</span></p>
<p class="MsoNormal">As with all things in Python, it is trivially easy to extend features by subclassing the relevant classes.<span>  </span>I subclassed the TextCtrlAutoComplete.<span>  </span>I went through a couple of ideas on how to accomplish what I was looking for:</p>
<ol type="1">
<li class="MsoNormal">I      tried to modify the for-loop in the onEnteredText to continue even after      it found a match and then append the items to a list.<span>  </span>Then after each run through the search I      would delete everything in the listctrl and then re-create the listctrl with on the relevant items.<span>  </span>This turned out to be eye-bleedingly slow.<span>  </span>It took about ~2 seconds for each letter typed to render the new box.</li>
<li class="MsoNormal">I then      tried to use my OntologyDatabase.SeachTree function to search the entire      tree at once and then render the listctrl from there.<span>  </span>However, this doesn’t work on partial      words, which is the whole thing I’m trying to accomplish with the auto-complete      box.</li>
</ol>
<p class="MsoNormal">None of these ideas panned out.<span>  </span>Instead I settled on using the listctlr.SortItems function.<span>  </span>This uses a provided function to evaluate pairwise comparisons of each list item and then uses QuickSort to arrange them.<span>  </span>I provided a comparison function (_sortItems) which places all words containing the search-term ABOVE non-containing words.<span>  </span>It then sorts by dictionary order within each class.<span>  </span>This solution sorts items as expected and works instantaneously, at least I can’t notice a slowdown while typing.</p>
<p class="MsoNormal">I came across two “gotchas” while programming today.<span>  </span>One is in wxWidgets and it was easily worked around.<span>  </span>It turns out that the listctrl GetItemData function is unreliable when the order is changing.<span>  </span>I found this in the <a href="http://www.nabble.com/Pb-with-sorting-wx.listCtrl-td20173789.html">post</a>.<span>  </span>So I changed my original:</p>
<pre>def _sortItems(self, data1, data2):
    text1 = self.GetItemData(data1)
    text2 = self.GetItemData(data2)</pre>
<p class="MsoNormal">To:</p>
<pre>text1 = self.itemDataMap[data1]
text2 = self.itemDataMap[data2]</pre>
<p class="MsoNormal">The other gotcha is that I came across is that Python string comparisons are NOT <a href="http://en.wikipedia.org/wiki/Lexicographical_order">lexographical</a>.<span>  </span>Simply put, this means that shorter words are ALWAYS smaller then longer words regardless of the letter composition.<span>  </span>I had to throw together a conversion tool quickly.<span>  </span>It’s an ugly wart that I’ll fix later, I PROMISE.<span>  </span>It errors out when there are non-letter characters or strange encodings that can’t be converted to integers.<span>  </span>I use a memoize decorator to cut down on the calculations.</p>
<p class="MsoNormal">Tomorrow’s project is to create the GEO searching tool and do some more dry-runs on the annotation before I make a big push to annotate next week.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Terminamos el curso de Python - Ejercicios y evaluación]]></title>
<link>http://javiercastrillo.wordpress.com/2008/12/21/terminamos-el-curso-de-python-ejercicios-y-evaluacion/</link>
<pubDate>Sun, 21 Dec 2008 11:54:56 +0000</pubDate>
<dc:creator>javiercastrillo</dc:creator>
<guid>http://javiercastrillo.wordpress.com/2008/12/21/terminamos-el-curso-de-python-ejercicios-y-evaluacion/</guid>
<description><![CDATA[wxPython, la biblioteca gráfica usada en el curso Según comentaba acá , este año tuvimos la inmensa ]]></description>
<content:encoded><![CDATA[wxPython, la biblioteca gráfica usada en el curso Según comentaba acá , este año tuvimos la inmensa ]]></content:encoded>
</item>

</channel>
</rss>
