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

<channel>
	<title>The Mouse Vs. The Python &#187; Cross-Platform</title>
	<atom:link href="http://www.blog.pythonlibrary.org/tag/cross-platform/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blog.pythonlibrary.org</link>
	<description>Python Programming from the Frontlines</description>
	<lastBuildDate>Sun, 08 Jan 2012 12:45:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to Find and List All Running Processes with Python</title>
		<link>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 18:34:46 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1271</guid>
		<description><![CDATA[The other day, I was tasked with finding a way to get a list of all running processes on a Windows XP virtual machine. I was also supposed to include information about how much CPU and memory each process used. Fortunately, this didn&#8217;t have to be a remote script, but one that could be run [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/" data-url="http://bit.ly/sJkCrz" data-text="How to Find and List All Running Processes with Python" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/";
			reddit_title = "How to Find and List All Running Processes with Python";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/"></g:plusone></div></div><p>The other day, I was tasked with finding a way to get a list of all running processes on a Windows XP virtual machine. I was also supposed to include information about how much CPU and memory each process used. Fortunately, this didn&#8217;t have to be a remote script, but one that could be run on the client. After a fair bit of Googling here and there, I finally found a solution. In this article, we&#8217;ll look at some of the rejects as well as the eventual solution, which happens to work cross-platform.<span id="more-1271"></span></p>
<p>One of the first scripts I found was <a href="http://mail.python.org/pipermail/python-win32/2006-March/004340.html">this one</a> back from March of 2006:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://mail.python.org/pipermail/python-win32/2006-March/004340.html</span>
<span style="color: #ff7700;font-weight:bold;">import</span> win32com.<span style="color: black;">client</span>
wmi=win32com.<span style="color: black;">client</span>.<span style="color: black;">GetObject</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'winmgmts:'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> wmi.<span style="color: black;">InstancesOf</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32_process'</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> p.<span style="color: black;">Name</span>, p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>, \
        <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UserModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>+<span style="color: #008000;">int</span><span style="color: black;">&#40;</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'KernelModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>
    children=wmi.<span style="color: black;">ExecQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Select * from win32_process where ParentProcessId=%s'</span> <span style="color: #66cc66;">%</span>p.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> child <span style="color: #ff7700;font-weight:bold;">in</span> children:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\t</span>'</span>,child.<span style="color: black;">Name</span>,child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>, \
            <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UserModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span>+<span style="color: #008000;">int</span><span style="color: black;">&#40;</span>child.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'KernelModeTime'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span><span style="color: black;">&#41;</span></pre>
<p>This script requires the <a href="http://sourceforge.net/projects/pywin32/">PyWin32 package</a> to work. However, while it&#8217;s a handy little script, it doesn&#8217;t show anything that I want except the ProcessId. I don&#8217;t really care about the user or kernel mode times (i.e. the total CPU time by user or kernel). Also I don&#8217;t really like working with the black magic of COM, so I ended up rejecting this one out of hand.</p>
<p>Next up was an <a href="http://code.activestate.com/recipes/303339-getting-process-information-on-windows/">ActiveState recipe</a>. It looked promising:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://code.activestate.com/recipes/303339-getting-process-information-on-windows/</span>
<span style="color: #ff7700;font-weight:bold;">import</span> win32pdh, <span style="color: #dc143c;">string</span>, win32api
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> procids<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;">#each instance is a process, you can have multiple processes w/same name</span>
    junk, instances = win32pdh.<span style="color: black;">EnumObjectItems</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>,<span style="color: #008000;">None</span>,<span style="color: #483d8b;">'process'</span>, win32pdh.<span style="color: black;">PERF_DETAIL_WIZARD</span><span style="color: black;">&#41;</span>
    proc_ids=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    proc_dict=<span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> instance <span style="color: #ff7700;font-weight:bold;">in</span> instances:
        <span style="color: #ff7700;font-weight:bold;">if</span> instance <span style="color: #ff7700;font-weight:bold;">in</span> proc_dict:
            proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span> = proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span> + <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            proc_dict<span style="color: black;">&#91;</span>instance<span style="color: black;">&#93;</span>=<span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> instance, max_instances <span style="color: #ff7700;font-weight:bold;">in</span> proc_dict.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> inum <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>max_instances<span style="color: #ff4500;">+1</span><span style="color: black;">&#41;</span>:
            hq = win32pdh.<span style="color: black;">OpenQuery</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># initializes the query handle </span>
            path = win32pdh.<span style="color: black;">MakeCounterPath</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #008000;">None</span>,<span style="color: #483d8b;">'process'</span>,instance, <span style="color: #008000;">None</span>, inum,<span style="color: #483d8b;">'ID Process'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
            counter_handle=win32pdh.<span style="color: black;">AddCounter</span><span style="color: black;">&#40;</span>hq, path<span style="color: black;">&#41;</span>
            win32pdh.<span style="color: black;">CollectQueryData</span><span style="color: black;">&#40;</span>hq<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#collects data for the counter </span>
            <span style="color: #008000;">type</span>, val = win32pdh.<span style="color: black;">GetFormattedCounterValue</span><span style="color: black;">&#40;</span>counter_handle, win32pdh.<span style="color: black;">PDH_FMT_LONG</span><span style="color: black;">&#41;</span>
            proc_ids.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>instance,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>val<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            win32pdh.<span style="color: black;">CloseQuery</span><span style="color: black;">&#40;</span>hq<span style="color: black;">&#41;</span>
&nbsp;
    proc_ids.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> proc_ids
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> procids<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Alas, while this also got me a list of processes from my Windows box (along with the PID), it didn&#8217;t give me any information on the CPU and memory utilization. I think this one could work if I used different counter names. I&#8217;m guessing if you wanted, you could figure out that information using MSDN. I didn&#8217;t want to mess with that, so I continued digging.</p>
<p>That recipe led me to the following one based on ctypes:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://code.activestate.com/recipes/305279/</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
Enumerates active processes as seen under windows Task Manager on Win NT/2k/XP using PSAPI.dll
(new api for processes) and using ctypes.Use it as you please.
&nbsp;
Based on information from http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175030&amp;ID=KB;EN-US;Q175030
&nbsp;
By Eric Koome
email ekoome@yahoo.com
license GPL
&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">from</span> ctypes <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#PSAPI.DLL</span>
psapi = windll.<span style="color: black;">psapi</span>
<span style="color: #808080; font-style: italic;">#Kernel32.DLL</span>
kernel = windll.<span style="color: black;">kernel32</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> EnumProcesses<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    arr = c_ulong <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">256</span>
    lpidProcess= arr<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    cb = sizeof<span style="color: black;">&#40;</span>lpidProcess<span style="color: black;">&#41;</span>
    cbNeeded = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    hModule = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    count = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    modname = c_buffer<span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span>
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_READ = 0x0010
&nbsp;
    <span style="color: #808080; font-style: italic;">#Call Enumprocesses to get hold of process id's</span>
    psapi.<span style="color: black;">EnumProcesses</span><span style="color: black;">&#40;</span>byref<span style="color: black;">&#40;</span>lpidProcess<span style="color: black;">&#41;</span>,
                        cb,
                        byref<span style="color: black;">&#40;</span>cbNeeded<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#Number of processes returned</span>
    nReturned = cbNeeded.<span style="color: black;">value</span>/sizeof<span style="color: black;">&#40;</span>c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    pidProcess = <span style="color: black;">&#91;</span>i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> lpidProcess<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>:nReturned<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> pid <span style="color: #ff7700;font-weight:bold;">in</span> pidProcess:
&nbsp;
        <span style="color: #808080; font-style: italic;">#Get handle to the process based on PID</span>
        hProcess = kernel.<span style="color: black;">OpenProcess</span><span style="color: black;">&#40;</span>PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                                      <span style="color: #008000;">False</span>, pid<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> hProcess:
            psapi.<span style="color: black;">EnumProcessModules</span><span style="color: black;">&#40;</span>hProcess, byref<span style="color: black;">&#40;</span>hModule<span style="color: black;">&#41;</span>, sizeof<span style="color: black;">&#40;</span>hModule<span style="color: black;">&#41;</span>, byref<span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            psapi.<span style="color: black;">GetModuleBaseNameA</span><span style="color: black;">&#40;</span>hProcess, hModule.<span style="color: black;">value</span>, modname, sizeof<span style="color: black;">&#40;</span>modname<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span> i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> modname <span style="color: #ff7700;font-weight:bold;">if</span> i <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">#-- Clean up</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>modname._length_<span style="color: black;">&#41;</span>:
                modname<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>=<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span>
&nbsp;
            kernel.<span style="color: black;">CloseHandle</span><span style="color: black;">&#40;</span>hProcess<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    EnumProcesses<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is pretty clever looking, but I&#8217;m pretty bad at parsing ctypes. It&#8217;s something I want to learn, but I had a deadline, doggone it! Plus this one only showed a list of running processes but no information about them. Fortunately, the author included a reference, but I decided to keep looking.</p>
<p>Next I found a thread about using Tim Golden&#8217;s handy <a href="http://tgolden.sc.sabren.com/python/wmi/index.html">WMI module</a> to do this sort of thing (below is copied right from the thread):</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># http://mail.python.org/pipermail/python-win32/2003-December/001482.html</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> processes = WMI.<span style="color: black;">InstancesOf</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Win32_Process'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>processes<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">41</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#91;</span>process.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Name'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span> <span style="color: #ff7700;font-weight:bold;">for</span> process <span style="color: #ff7700;font-weight:bold;">in</span> processes<span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># get</span>
the process names
<span style="color: black;">&#91;</span>u<span style="color: #483d8b;">'System Idle Process'</span>, u<span style="color: #483d8b;">'System'</span>, u<span style="color: #483d8b;">'SMSS.EXE'</span>, u<span style="color: #483d8b;">'CSRSS.EXE'</span>,
u<span style="color: #483d8b;">'WINLOGON.EXE'</span>, u<span style="color: #483d8b;">'SERVICES.EXE'</span>, u<span style="color: #483d8b;">'LSASS.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>,
u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SVCHOST.EXE'</span>, u<span style="color: #483d8b;">'SPOOLSV.EXE'</span>,
u<span style="color: #483d8b;">'ati2evxx.exe'</span>, u<span style="color: #483d8b;">'BAsfIpM.exe'</span>, u<span style="color: #483d8b;">'defwatch.exe'</span>, u<span style="color: #483d8b;">'inetinfo.exe'</span>,
u<span style="color: #483d8b;">'mdm.exe'</span>, u<span style="color: #483d8b;">'rtvscan.exe'</span>, u<span style="color: #483d8b;">'SCARDSVR.EXE'</span>, u<span style="color: #483d8b;">'WLTRYSVC.EXE'</span>,
u<span style="color: #483d8b;">'BCMWLTRY.EXE'</span>, u<span style="color: #483d8b;">'EXPLORER.EXE'</span>, u<span style="color: #483d8b;">'Apoint.exe'</span>, u<span style="color: #483d8b;">'carpserv.exe'</span>,
u<span style="color: #483d8b;">'atiptaxx.exe'</span>, u<span style="color: #483d8b;">'quickset.exe'</span>, u<span style="color: #483d8b;">'DSentry.exe'</span>, u<span style="color: #483d8b;">'Directcd.exe'</span>,
u<span style="color: #483d8b;">'vptray.exe'</span>, u<span style="color: #483d8b;">'ApntEx.exe'</span>, u<span style="color: #483d8b;">'FaxCtrl.exe'</span>, u<span style="color: #483d8b;">'digstream.exe'</span>,
u<span style="color: #483d8b;">'CTFMON.EXE'</span>, u<span style="color: #483d8b;">'wuauclt.exe'</span>, u<span style="color: #483d8b;">'IEXPLORE.EXE'</span>, u<span style="color: #483d8b;">'Pythonwin.exe'</span>,
u<span style="color: #483d8b;">'MMC.EXE'</span>, u<span style="color: #483d8b;">'OUTLOOK.EXE'</span>, u<span style="color: #483d8b;">'LineMgr.exe'</span>, u<span style="color: #483d8b;">'SAPISVR.EXE'</span>,
u<span style="color: #483d8b;">'WMIPRVSE.EXE'</span><span style="color: black;">&#93;</span>
&nbsp;
Here <span style="color: #ff7700;font-weight:bold;">is</span> how to get a single process <span style="color: #ff7700;font-weight:bold;">and</span> get its PID.
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> p = WMI.<span style="color: black;">ExecQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'select * from Win32_Process where
Name=&quot;Pythonwin.exe&quot;'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#91;</span>prop.<span style="color: black;">Name</span> <span style="color: #ff7700;font-weight:bold;">for</span> prop <span style="color: #ff7700;font-weight:bold;">in</span> p<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">Properties_</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># let's look at all the</span>
process <span style="color: #008000;">property</span> names
<span style="color: black;">&#91;</span>u<span style="color: #483d8b;">'Caption'</span>, u<span style="color: #483d8b;">'CommandLine'</span>, u<span style="color: #483d8b;">'CreationClassName'</span>, u<span style="color: #483d8b;">'CreationDate'</span>,
u<span style="color: #483d8b;">'CSCreationClassName'</span>, u<span style="color: #483d8b;">'CSName'</span>, u<span style="color: #483d8b;">'Description'</span>, u<span style="color: #483d8b;">'ExecutablePath'</span>,
u<span style="color: #483d8b;">'ExecutionState'</span>, u<span style="color: #483d8b;">'Handle'</span>, u<span style="color: #483d8b;">'HandleCount'</span>, u<span style="color: #483d8b;">'InstallDate'</span>,
u<span style="color: #483d8b;">'KernelModeTime'</span>, u<span style="color: #483d8b;">'MaximumWorkingSetSize'</span>, u<span style="color: #483d8b;">'MinimumWorkingSetSize'</span>,
u<span style="color: #483d8b;">'Name'</span>, u<span style="color: #483d8b;">'OSCreationClassName'</span>, u<span style="color: #483d8b;">'OSName'</span>, u<span style="color: #483d8b;">'OtherOperationCount'</span>,
u<span style="color: #483d8b;">'OtherTransferCount'</span>, u<span style="color: #483d8b;">'PageFaults'</span>, u<span style="color: #483d8b;">'PageFileUsage'</span>,
u<span style="color: #483d8b;">'ParentProcessId'</span>, u<span style="color: #483d8b;">'PeakPageFileUsage'</span>, u<span style="color: #483d8b;">'PeakVirtualSize'</span>,
u<span style="color: #483d8b;">'PeakWorkingSetSize'</span>, u<span style="color: #483d8b;">'Priority'</span>, u<span style="color: #483d8b;">'PrivatePageCount'</span>, u<span style="color: #483d8b;">'ProcessId'</span>,
u<span style="color: #483d8b;">'QuotaNonPagedPoolUsage'</span>, u<span style="color: #483d8b;">'QuotaPagedPoolUsage'</span>,
u<span style="color: #483d8b;">'QuotaPeakNonPagedPoolUsage'</span>, u<span style="color: #483d8b;">'QuotaPeakPagedPoolUsage'</span>,
u<span style="color: #483d8b;">'ReadOperationCount'</span>, u<span style="color: #483d8b;">'ReadTransferCount'</span>, u<span style="color: #483d8b;">'SessionId'</span>, u<span style="color: #483d8b;">'Status'</span>,
u<span style="color: #483d8b;">'TerminationDate'</span>, u<span style="color: #483d8b;">'ThreadCount'</span>, u<span style="color: #483d8b;">'UserModeTime'</span>, u<span style="color: #483d8b;">'VirtualSize'</span>,
u<span style="color: #483d8b;">'WindowsVersion'</span>, u<span style="color: #483d8b;">'WorkingSetSize'</span>, u<span style="color: #483d8b;">'WriteOperationCount'</span>,
u<span style="color: #483d8b;">'WriteTransferCount'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> p<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">Properties_</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ProcessId'</span><span style="color: black;">&#41;</span>.<span style="color: black;">Value</span> <span style="color: #808080; font-style: italic;"># get our ProcessId</span>
<span style="color: #ff4500;">928</span></pre>
<p>This is some cool stuff and I use Golden&#8217;s modules in some of my other code. However, I was still uncertain as to which counters to use to get to my information. I thought most of this stuff would just be coded for me or something! Well, it turned out that there is a package out there that does exactly what I needed AND it works on all the three of the major platforms! Amazing!</p>
<h2>The Cross-Platform Solution!</h2>
<p>The package&#8217;s name is <a href="http://code.google.com/p/psutil/">psutil</a> and it was what I decided to use. Here&#8217;s what I ended up with:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> psutil
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
logPath = r<span style="color: #483d8b;">'some<span style="color: #000099; font-weight: bold;">\p</span>ath<span style="color: #000099; font-weight: bold;">\p</span>roclogs'</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>logPath<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">os</span>.<span style="color: black;">mkdir</span><span style="color: black;">&#40;</span>logPath<span style="color: black;">&#41;</span>
&nbsp;
separator = <span style="color: #483d8b;">&quot;-&quot;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">80</span>
format = <span style="color: #483d8b;">&quot;%7s %7s %12s %12s %30s, %s&quot;</span>
format2 = <span style="color: #483d8b;">&quot;%7.4f %7.2f %12s %12s %30s, %s&quot;</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
    procs = psutil.<span style="color: black;">get_process_list</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    procs = <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>procs, key=<span style="color: #ff7700;font-weight:bold;">lambda</span> proc: proc.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
    logPath = r<span style="color: #483d8b;">'some<span style="color: #000099; font-weight: bold;">\p</span>ath<span style="color: #000099; font-weight: bold;">\p</span>roclogs<span style="color: #000099; font-weight: bold;">\p</span>rocLog%i.log'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>logPath, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>separator + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: black;">ctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>format <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%CPU&quot;</span>, <span style="color: #483d8b;">&quot;%MEM&quot;</span>, <span style="color: #483d8b;">&quot;VMS&quot;</span>, <span style="color: #483d8b;">&quot;RSS&quot;</span>, <span style="color: #483d8b;">&quot;NAME&quot;</span>, <span style="color: #483d8b;">&quot;PATH&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> proc <span style="color: #ff7700;font-weight:bold;">in</span> procs:
        cpu_percent = proc.<span style="color: black;">get_cpu_percent</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        mem_percent = proc.<span style="color: black;">get_memory_percent</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        rss, vms = proc.<span style="color: black;">get_memory_info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        rss = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>rss<span style="color: black;">&#41;</span>
        vms = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>vms<span style="color: black;">&#41;</span>
        name = proc.<span style="color: black;">name</span>
        path = proc.<span style="color: black;">path</span>
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>format2 <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>cpu_percent, mem_percent, vms, rss, name, path<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Finished log update!&quot;</span>
    <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;writing new log data!&quot;</span></pre>
<p>Yes, it&#8217;s an infinite loop and yes, that&#8217;s usually a very bad thing to do (except in GUI programming). However, for my purpose, I needed a way to check the user&#8217;s processes every 5 minutes or so to see what was causing the machine to act so weird. Thus, the script needs to run forever and log the results to uniquely named files. That&#8217;s all this script does, along with a little formatting magic. Feel free to use it or not as you see fit.</p>
<p>I hope you found this collection of material helpful. Hopefully it will save you all the digging I went through!</p>
<p><em>Note: While this last script appears to work just fine on Windows XP, on Windows 7 32 and 64-bit, you will get an &#8220;Access Denied&#8221; traceback, I suspect this is caused by Window 7&#8242;s increased security, but I will try to find a workaround.</p>
<p>UPDATE (10/09/2010) &#8211; The psutil folks don&#8217;t know why it doesn&#8217;t work, but one of their developers has confirmed the issue. You can follow along on their <a href="http://groups.google.com/group/psutil/browse_frm/thread/ec8bf72fa18f79a2">Google Groups list</a>.<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A bbfreeze Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:23:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[bbfreeze]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Distribution]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1137</guid>
		<description><![CDATA[The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/" data-url="http://bit.ly/t6R0h2" data-text="A bbfreeze Tutorial &#8211; Build a Binary Series!" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/";
			reddit_title = "A bbfreeze Tutorial &#8211; Build a Binary Series!";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/"></g:plusone></div></div><p>The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. You can also freeze multiple scripts at once, include the Python interpreter and more. According to bbfreeze&#8217;s PyPI entry, it&#8217;s only been tested with Python 2.4-2.5, so keep that in mind. However, I was able to use it with Python 2.6 with no obvious problems.<span id="more-1137"></span></p>
<h2>Getting Started with bbfreeze</h2>
<p>You can use easy_install to download and install bbfreeze or you can just download its source or the egg file directly from the <a href="http://pypi.python.org/pypi/bbfreeze/">Python Package Index</a> (PyPI). In this article, we&#8217;ll try using it on a simple configuration file generator script and we&#8217;ll also try it against a lame wxPython program. My test machine was a Windows 7 Home Edition 32-bit laptop with bbfreeze 0.96.5, and Python 2.6.4. Let&#8217;s start with the configuration script:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># config_1.py</span>
<span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig2.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>This script has a couple of functions that are pointless, but we&#8217;ll leave them in for illustrative purposes. According to the bbfreeze documentation, we should be able to create a binary with the following string typed into the command line:</p>
<p><code><br />
bb-freeze config_1.py<br />
</code></p>
<p>This assumes that you have &#8220;C:\Python26\Scripts&#8221; on your path. If you don&#8217;t, you&#8217;ll need to type the complete path out (i.e. &#8220;C:\Python26\Scripts\bb-freeze config_1.py&#8221;). When I ran this, I got an error. Here it is:</p>
<pre class="python">Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\S</span>cripts<span style="color: #000099; font-weight: bold;">\b</span>b-freeze-script.py&quot;</span>, line <span style="color: #ff4500;">8</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    load_entry_point<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bbfreeze==0.96.5'</span>, <span style="color: #483d8b;">'console_scripts'</span>, <span style="color: #483d8b;">'bb-freeze'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\_</span>_init__.py&quot;</span>, line <span style="color: #ff4500;">18</span>, <span style="color: #ff7700;font-weight:bold;">in</span> main
    f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">474</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #0000cd;">__call__</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">addModule</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;encodings.*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">411</span>, <span style="color: #ff7700;font-weight:bold;">in</span> addModule
    <span style="color: #008000;">self</span>.<span style="color: black;">mf</span>.<span style="color: black;">import_hook</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">-2</span><span style="color: black;">&#93;</span>, fromlist=<span style="color: #483d8b;">&quot;*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">256</span>, <span style="color: #ff7700;font-weight:bold;">in</span> import_hook
    modules.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ensure_fromlist</span><span style="color: black;">&#40;</span>m, fromlist<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">345</span>, <span style="color: #ff7700;font-weight:bold;">in</span> ensure_fromlist
    fromlist.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">find_all_submodules</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">369</span>, <span style="color: #ff7700;font-weight:bold;">in</span> find_all_submodules
    <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>path, mode, typ<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> ifilter<span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, imap<span style="color: black;">&#40;</span>moduleInfoForPath, names<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
<span style="color: #008000;">NameError</span>: <span style="color: #ff7700;font-weight:bold;">global</span> name <span style="color: #483d8b;">'ifilter'</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined</pre>
<p>It would seem that the &#8220;modulegraph.py&#8221; file is missing an import from the <a href="http://docs.python.org/library/itertools.html">itertools</a> library, which is included with Python. I edited my copy of &#8220;modulegraph.py&#8221; to include the following line at the top of the file: &#8220;from itertools import ifilter&#8221;. This got rid of that traceback, but it raised another because &#8220;imap&#8221; wasn&#8217;t defined either. To fix the second error, I changed my import to &#8220;from itertools import ifilter,imap&#8221; and then it ran with no problems and produced a binary in a &#8220;dist&#8221; folder along with nine other files (see screenshot below).</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png" alt="bbfreeze_dir.png" title="bbfreeze_dir.png" width="599" height="324" class="aligncenter size-full wp-image-1148" /></a></p>
<h2>Using bbfreeze&#8217;s Advanced Configuration</h2>
<p>The PyPI page for bbfreeze (which is also its home page) has very little documentation. However, the page does say that the preferred way to use bbfreeze is with little scripts. We&#8217;re going to try using creating a binary with the lame wxPython, mentioned earlier. Here&#8217;s the wx code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;cxFreeze Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s create a simple freezing script!</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
f = Freezer<span style="color: black;">&#40;</span>distdir=<span style="color: #483d8b;">&quot;bb-binary&quot;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span><span style="color: black;">&#41;</span>
f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>First off, we import the <em>Freezer</em> class from the bbfreeze package. Freezer accepts three arguments: a destination folder, an includes iterable and an excludes iterable (i.e. a tuple or list). Just to see how well bbfreeze works with only its defaults, we leave out the includes and excludes tuples/lists. Once you have a Freezer object, you can add your script(s) by calling the Freezer object name&#8217;s <em>addScript</em> method. Then you just need to call the object (i.e.  f() ). If you do all that, you should end up with a 14.5 MB folder holding 18 files. When I ran the sampleApp.exe file, it ran just fine and was properly themed, however it also had a console screen. To figure out the correct syntax, I used <a href="http://code.google.com/p/gui2exe/">GUI2Exe</a>. Here&#8217;s the new code:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup2.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
&nbsp;
bbFreeze_Class = Freezer<span style="color: black;">&#40;</span><span style="color: #483d8b;">'dist'</span>, includes=includes, excludes=excludes<span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span>, gui_only=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">use_compression</span> = <span style="color: #ff4500;">0</span>
bbFreeze_Class.<span style="color: black;">include_py</span> = <span style="color: #008000;">True</span>
bbFreeze_Class<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>If you run this, you should end up with a &#8220;dist&#8221; folder that contains 18 files and is 16.6 MB in size. Notice that we added a second argument to the <em>addScript</em> method: gui_only=True. This makes that annoying console go away. We also set compression to zero (no compression, I think) and include the Python interpreter. Turning on compression only reduced the result down to 14.3 MB though. </p>
<p>The bbfreeze package also handles &#8220;recipes&#8221; and includes several examples, however they are not documented well either and I couldn&#8217;t figure out how to include them with my current examples. Feel free to figure them out on your own!</p>
<h2>Wrapping Up</h2>
<p>Well, now you should know the basics of using bbfreeze to create binaries from your programs. I hope you found this helpful. The last article in this series will be on GUI2Exe. Look for it soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A cx_Freeze Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 00:40:32 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[cx_freeze]]></category>
		<category><![CDATA[Distribution]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1112</guid>
		<description><![CDATA[In this article, we will be learning about cx_Freeze, a cross-platform set of scripts designed to &#8220;freeze&#8221; Python scripts into executables in a manner similar to py2exe, PyInstaller, etc. We will freeze one console script and one window (i.e GUI) script, using the examples from the previous article in this series. If you haven&#8217;t done [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/" data-url="http://bit.ly/s8dadO" data-text="A cx_Freeze Tutorial &#8211; Build a Binary Series!" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/";
			reddit_title = "A cx_Freeze Tutorial &#8211; Build a Binary Series!";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/"></g:plusone></div></div><p>In this article, we will be learning about cx_Freeze, a cross-platform set of scripts designed to &#8220;freeze&#8221; Python scripts into executables in a manner similar to py2exe, PyInstaller, etc. We will freeze one console script and one window (i.e GUI) script, using the examples from the previous article in this series. If you haven&#8217;t done so already, you can get cx_Freeze <a href="http://cx-freeze.sourceforge.net/">here</a>. Let&#8217;s get this party started, shall we?<span id="more-1112"></span></p>
<h2>Getting Started with cx_Freeze</h2>
<p>As mentioned on the cx_Freeze website, there are three ways to use this script. The first is to just use the included cxfreeze script; the second is to create a distutils setup script (think py2exe) which you can save for future use; and the third is to work with the internals of cxfreeze. We will focus on the first two ways of using cx_Freeze. We&#8217;ll begin with the console script:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig2.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>All this script does is create a really simple configuration file using Michael Foord&#8217;s <a href="http://www.voidspace.org.uk/python/configobj.html">configobj</a> module. You can set it up to read the config too, but for this example, we&#8217;ll skip that. Let&#8217;s find out how to build a binary with cx_Freeze! According to the documentation, all it should take is the following string on the command line (assuming you are in the correct directory):</p>
<p><code><br />
cxfreeze config_1.py --target-dir dirName<br />
</code></p>
<p>This assumes that you have &#8220;C:\PythonXX\Scripts&#8221; on your path. If not, you&#8217;ll either have to fix that or type out the fully qualified path. Anyway, if the cxfreeze script run correctly, you should have a folder with the following contents:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/cx_freeze_dir.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/cx_freeze_dir.png" alt="cx_freeze_dir.png" title="cx_freeze_dir.png" width="587" height="244" class="aligncenter size-full wp-image-1118" /></a></p>
<p>As you can see, the total file size should be 4.81 MB or almost 5 megabytes. That was pretty easy. It even picked up the configobj module without our having to tell it to, something that PyInstaller failed to do. There are 18 command line arguments you can pass to cx_Freeze to control how it does things. These range from what modules to include or exclude, optimization, compression, include a zip file, path manipulation and more. Now let&#8217;s try something a little more advanced.</p>
<h2>&#8220;Advanced&#8221; cx_Freeze &#8211; Using a setup.py File</h2>
<p>First off we need a script to use. For this one, we&#8217;ll use that simple wxPython script from the PyInstaller article:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;cxFreeze Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s create a <strong>setup.py</strong> file in the cx_Freeze style:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> cx_Freeze <span style="color: #ff7700;font-weight:bold;">import</span> setup, Executable
&nbsp;
setup<span style="color: black;">&#40;</span>
    name = <span style="color: #483d8b;">&quot;wxSampleApp&quot;</span>,
    version = <span style="color: #483d8b;">&quot;0.1&quot;</span>,
    description = <span style="color: #483d8b;">&quot;An example wxPython script&quot;</span>,
    executables = <span style="color: black;">&#91;</span>Executable<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.pyw&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span></pre>
<p>As you can see, this is a pretty simple one. We import a couple classes from cx_Freeze and pass some parameters into them. In this case, we give the <em>setup</em> class a name, version, description and and <em>Executable </em>class. The Executable class also gets one parameter, the script name that it will use to create the binary from. To get this to build the binary, you need to do the following on the command line:</p>
<p><code><br />
python setup.py build<br />
</code></p>
<p>After running this, you should end up with the following folders: &#8220;build\exe.win32-2.6&#8243;. Inside that last folder are 17 files that total 15.3 MB. When you run the sampleApp.exe file, you will notice that we&#8217;ve screwed something up. There&#8217;s a console window loading in addition to our GUI!!! To rectify this, we&#8217;ll need to change our setup file slightly. Take a look at our new one:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> cx_Freeze <span style="color: #ff7700;font-weight:bold;">import</span> setup, Executable
&nbsp;
exe = Executable<span style="color: black;">&#40;</span>
    script=<span style="color: #483d8b;">&quot;sampleApp.pyw&quot;</span>,
    base=<span style="color: #483d8b;">&quot;Win32GUI&quot;</span>,
    <span style="color: black;">&#41;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    name = <span style="color: #483d8b;">&quot;wxSampleApp&quot;</span>,
    version = <span style="color: #483d8b;">&quot;0.1&quot;</span>,
    description = <span style="color: #483d8b;">&quot;An example wxPython script&quot;</span>,
    executables = <span style="color: black;">&#91;</span>exe<span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span></pre>
<p>First off, we separated the <em>Executable</em> class from the <em>setup</em> class and assigned the Executable class to a variable. We also added a second parameter to the Executable class that is key. That parameter is called &#8220;base&#8221;. By setting <strong>base=&#8221;Win32GUI&#8221;</strong>, we are able to suppress the console window. A good way to learn the many other options that we can use with cx_Freeze is to use GUI2Exe to generate the setup.py files for us. The documentation on the cx_Freeze website shows the many other options that the Executable class takes. Oddly enough, I couldn&#8217;t find any information about what the <em>setup</em> class takes for arguments other than just the source itself, which has very little comments. Good luck figuring that bit out.</p>
<h2>Wrapping Up</h2>
<p>Now you should know how to create binaries with cx_Freeze. It&#8217;s pretty easy to do and it&#8217;s nice that they&#8217;ve created a method to create binaries in a cross-platform way. Have fun!</p>
<h2>Further Reading</h2>
<ul>
<li><a href="http://stackoverflow.com/questions/2880316/hide-console-window-with-wxpython-and-cxfreeze">Stackoverflow</a></li>
<li>cx_Freeze <a href="http://cx-freeze.sourceforge.net/">official site</a>, <a href="https://lists.sourceforge.net/lists/listinfo/cx-freeze-users">mailing list</a></li>
<li>GUI2Exe <a href="http://code.google.com/p/gui2exe/">website</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a Simple Photo Viewer with wxPython</title>
		<link>http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 02:27:06 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wxPython]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=717</guid>
		<description><![CDATA[The other day, I was chatting with some wxPython newbies on the wxPython IRC channel and one of them wanted to know how to display images in wx. There are lots of different ways to do this, but I had a pre-made solution that I&#8217;d cobbled together a couple of years ago for work. Since [...]]]></description>
			<content:encoded><![CDATA[<div class="socialize-in-content" style="float:left;"><div class="socialize-in-button socialize-in-button-left"><a href="http://twitter.com/share" class="twitter-share-button" data-counturl="http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/" data-url="http://bit.ly/sGlqU6" data-text="Creating a Simple Photo Viewer with wxPython" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-left"><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/&amp;layout=button_count&amp;show_faces=true&amp;width=100&amp;action=like&amp;font=arial&amp;colorscheme=light&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px !important; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-left"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/";
			reddit_title = "Creating a Simple Photo Viewer with wxPython";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-left"><g:plusone size="small" href="http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/"></g:plusone></div></div><p>The other day, I was chatting with some wxPython newbies on the wxPython IRC channel and one of them wanted to know how to display images in wx. There are lots of different ways to do this, but I had a pre-made solution that I&#8217;d cobbled together a couple of years ago for work. Since this is a fairly popular topic, I thought it would be wise to let you, dear reader, in on the secret. <span id="more-717"></span></p>
<h2>Image Viewer Take One</h2>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/imageViewer1.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/imageViewer1-150x150.png" alt="" title="imageViewer1" width="150" height="150" class="aligncenter size-thumbnail wp-image-723" /></a></p>
<p>One of the simplest ways to display an image in wxPython is to use the wx.StaticBitmap to do your dirty work. In this example, we want a placeholder for the image, so we&#8217;ll use wx.EmptyImage for that. Finally, we need a way to scale the image down if it&#8217;s too large for either our resolution or our application. For that, we&#8217;ll use a tip I received from the illustrious Andrea Gavana (creator of the AGW library). That&#8217;s enough for the introductions, let&#8217;s look at the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> PhotoCtrl<span style="color: black;">&#40;</span>wx.<span style="color: black;">App</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, redirect=<span style="color: #008000;">False</span>, filename=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        wx.<span style="color: black;">App</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, redirect, filename<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">frame</span> = wx.<span style="color: black;">Frame</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, title=<span style="color: #483d8b;">'Photo Control'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">panel</span> = wx.<span style="color: black;">Panel</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">frame</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> = <span style="color: #ff4500;">240</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">createWidgets</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">frame</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        instructions = <span style="color: #483d8b;">'Browse for an image'</span>
        img = wx.<span style="color: black;">EmptyImage</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">240</span>,<span style="color: #ff4500;">240</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span> = wx.<span style="color: black;">StaticBitmap</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>, wx.<span style="color: black;">ID_ANY</span>,
                                         wx.<span style="color: black;">BitmapFromImage</span><span style="color: black;">&#40;</span>img<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        instructLbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>, label=instructions<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span> = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>, size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">200</span>,<span style="color: #ff4500;">-1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        browseBtn = wx.<span style="color: black;">Button</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>, label=<span style="color: #483d8b;">'Browse'</span><span style="color: black;">&#41;</span>
        browseBtn.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_BUTTON</span>, <span style="color: #008000;">self</span>.<span style="color: black;">onBrowse</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span> = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span> = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">StaticLine</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>, wx.<span style="color: black;">ID_ANY</span><span style="color: black;">&#41;</span>,
                           <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">EXPAND</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>instructLbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>browseBtn, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Fit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">frame</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> onBrowse<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Browse for file
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wildcard = <span style="color: #483d8b;">&quot;JPEG files (*.jpg)|*.jpg&quot;</span>
        dialog = wx.<span style="color: black;">FileDialog</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, <span style="color: #483d8b;">&quot;Choose a file&quot;</span>,
                               wildcard=wildcard,
                               style=wx.<span style="color: black;">OPEN</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> dialog.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == wx.<span style="color: black;">ID_OK</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>dialog.<span style="color: black;">GetPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        dialog.<span style="color: black;">Destroy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">onView</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> onView<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        filepath = <span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span>.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        img = wx.<span style="color: black;">Image</span><span style="color: black;">&#40;</span>filepath, wx.<span style="color: black;">BITMAP_TYPE_ANY</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># scale the image, preserving the aspect ratio</span>
        W = img.<span style="color: black;">GetWidth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        H = img.<span style="color: black;">GetHeight</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> W <span style="color: #66cc66;">&gt;</span> H:
            NewW = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span>
            NewH = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> <span style="color: #66cc66;">*</span> H / W
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            NewH = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span>
            NewW = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> <span style="color: #66cc66;">*</span> W / H
        img = img.<span style="color: black;">Scale</span><span style="color: black;">&#40;</span>NewW,NewH<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span>.<span style="color: black;">SetBitmap</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">BitmapFromImage</span><span style="color: black;">&#40;</span>img<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">Refresh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    app = PhotoCtrl<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>You may be thinking that this example is kind of complex. Well, it&#8217;s actually not that bad since the code is only 76 lines long! Let&#8217;s go over the various methods to see what&#8217;s happening. </p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, redirect=<span style="color: #008000;">False</span>, filename=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        wx.<span style="color: black;">App</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, redirect, filename<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">frame</span> = wx.<span style="color: black;">Frame</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, title=<span style="color: #483d8b;">'Photo Control'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">panel</span> = wx.<span style="color: black;">Panel</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">frame</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> = <span style="color: #ff4500;">500</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">createWidgets</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">frame</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>The __init__ initializes out wx.App object, instantiates a frame and adds a panel as the frame&#8217;s only child. We set the photo&#8217;s max size to 500 pixels so that it&#8217;s easy to see, but won&#8217;t be too big for our monitor. Then we call our <em>createWidgets </em>method and finally display the frame by calling Show(). Since we already went over the EmptyImage widget earlier, I think it&#8217;s safe to skip the <em>createWidgets </em>method and move on with one caveat. Notice the last three lines from <em>createWidgets</em>:</p>
<pre class="python"><span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Fit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">frame</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This will set the panel&#8217;s sizer and then fit the frame to the widgets contained in the sizer. This will keep out application looking tidy as we won&#8217;t have a bunch of extra pixels worth of panel sticking out in odd places. Try it without these lines and see what happens if you can&#8217;t picture it!</p>
<p>Our <em>onBrowse</em> method is next:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> onBrowse<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Browse for file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    wildcard = <span style="color: #483d8b;">&quot;JPEG files (*.jpg)|*.jpg&quot;</span>
    dialog = wx.<span style="color: black;">FileDialog</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, <span style="color: #483d8b;">&quot;Choose a file&quot;</span>,
                           wildcard=wildcard,
                           style=wx.<span style="color: black;">OPEN</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> dialog.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == wx.<span style="color: black;">ID_OK</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span>.<span style="color: black;">SetValue</span><span style="color: black;">&#40;</span>dialog.<span style="color: black;">GetPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    dialog.<span style="color: black;">Destroy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">onView</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>First off, we create a wildcard that specifies only JPEG files and then we pass it to our wx.FileDialog constructor. This will limit the dialog in such a way that it only shows JPEG files. If the user presses the OK (or Open) button, then we set the <em>photoTxt </em>control&#8217;s value to the path of the file chosen. We should probably add some error checking to make sure the file is a valid JPEG file, but we&#8217;ll leave that as an exercise for the reader. After the value is set, the dialog is destroyed and <em>onView </em>is called, which will show the picture. Let&#8217;s see how that works:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> onView<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    filepath = <span style="color: #008000;">self</span>.<span style="color: black;">photoTxt</span>.<span style="color: black;">GetValue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    img = wx.<span style="color: black;">Image</span><span style="color: black;">&#40;</span>filepath, wx.<span style="color: black;">BITMAP_TYPE_ANY</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># scale the image, preserving the aspect ratio</span>
    W = img.<span style="color: black;">GetWidth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    H = img.<span style="color: black;">GetHeight</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> W <span style="color: #66cc66;">&gt;</span> H:
        NewW = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span>
        NewH = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> <span style="color: #66cc66;">*</span> H / W
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        NewH = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span>
        NewW = <span style="color: #008000;">self</span>.<span style="color: black;">PhotoMaxSize</span> <span style="color: #66cc66;">*</span> W / H
    img = img.<span style="color: black;">Scale</span><span style="color: black;">&#40;</span>NewW,NewH<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span>.<span style="color: black;">SetBitmap</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">BitmapFromImage</span><span style="color: black;">&#40;</span>img<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">panel</span>.<span style="color: black;">Refresh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Fit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">frame</span><span style="color: black;">&#41;</span></pre>
<p>First off, we grab the image&#8217;s path from the photo text control and create an instance of wx.Image using that information. Next, we grab the file&#8217;s width and height and use a simple calculation to scale the picture down to the size we specified at the beginning. Then we call our StaticBitmap&#8217;s SetBitmap() method to show the image. Finally, we refresh the panel so that everything repaints and we call our sizer&#8217;s Fit method so that the frame resizes to fit the new photo in an appropriate fashion. Now we have a fully functional image viewer!</p>
<h2>Making a Better Photo Viewer</h2>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/imageViewer2_2.jpg"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/imageViewer2_2-150x150.jpg" alt="" title="imageViewer2_2" width="150" height="150" class="aligncenter size-thumbnail wp-image-727" /></a></p>
<p>If you&#8217;re one of my astute readers, you&#8217;ll notice that every time you want to view a new picture in your picture folder, you&#8217;ll need to browse for it. That&#8217;s not a good user experience, is it? Let&#8217;s try to expand our control so we can do the following:</p>
<ul>
<li>Add a Previous and Next button to go backwards and forwards over the pictures</li>
<li>Create a button that can &#8220;play&#8221; the photos (i.e. change photos every so often)</li>
<li>Make the Previous and Next buttons &#8220;smart&#8221; enough to start over when they reach the end of the list of files</li>
</ul>
<p>For our first trick, we&#8217;ll put the Frame and Panel into separate classes and just use PySimpleApp instead of App. This makes our code a little more orderly, although it also has some drawbacks (such as communicating between the frame and panel). The panel will hold most of our widgets, so let&#8217;s look at the frame class first since it&#8217;s much simpler:</p>
<pre class="python"><span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> ViewerFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, title=<span style="color: #483d8b;">&quot;Image Viewer&quot;</span><span style="color: black;">&#41;</span>
        panel = ViewerPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">folderPath</span> = <span style="color: #483d8b;">&quot;&quot;</span>
        Publisher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">resizeFrame</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;resize&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">initToolbar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span> = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>panel, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">sizer</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>.<span style="color: black;">Fit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Center</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> initToolbar<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Initialize the toolbar
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">toolbar</span> = <span style="color: #008000;">self</span>.<span style="color: black;">CreateToolBar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">toolbar</span>.<span style="color: black;">SetToolBitmapSize</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">16</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        open_ico = wx.<span style="color: black;">ArtProvider</span>.<span style="color: black;">GetBitmap</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">ART_FILE_OPEN</span>, wx.<span style="color: black;">ART_TOOLBAR</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">16</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        openTool = <span style="color: #008000;">self</span>.<span style="color: black;">toolbar</span>.<span style="color: black;">AddSimpleTool</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">ID_ANY</span>, open_ico, <span style="color: #483d8b;">&quot;Open&quot;</span>, <span style="color: #483d8b;">&quot;Open an Image Directory&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_MENU</span>, <span style="color: #008000;">self</span>.<span style="color: black;">onOpenDirectory</span>, openTool<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">toolbar</span>.<span style="color: black;">Realize</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onOpenDirectory<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Opens a DirDialog to allow the user to open a folder with pictures
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        dlg = wx.<span style="color: black;">DirDialog</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #483d8b;">&quot;Choose a directory&quot;</span>,
                           style=wx.<span style="color: black;">DD_DEFAULT_STYLE</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> dlg.<span style="color: black;">ShowModal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == wx.<span style="color: black;">ID_OK</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">folderPath</span> = dlg.<span style="color: black;">GetPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">self</span>.<span style="color: black;">folderPath</span>
            picPaths = <span style="color: #dc143c;">glob</span>.<span style="color: #dc143c;">glob</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">folderPath</span> + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>*.jpg&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> picPaths
        Publisher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">sendMessage</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;update images&quot;</span>, picPaths<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> resizeFrame<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sizer</span>.<span style="color: black;">Fit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span></pre>
<p>If you&#8217;ve read much wxPython code, then the above should be pretty familiar to you. We construct the frame as usual, then we create an instance of our <em>ViewerPanel </em>and pass it <em>self</em> so that the panel will have a reference to the frame. The next important bit is the creation of our Pubsub listener singleton. This will call the frame&#8217;s <em>resizeFrame</em> method, which is only called when we display a new picture. The next important piece is the call to <em>initToolbar</em>, which creates a toolbar on our frame. The other method of the frame is <em>onOpenDirectory</em>, which is very similar to the browse function from our first application. In this case, we want to select an entire folder and only pull the paths of the JPEG files from it. Thus, we use Python&#8217;s glob file to do that. Once that&#8217;s done, it sends a pubsub message to the panel along with the list of picture paths.</p>
<p>Now we can take a look at the most important piece of code: the <strong>ViewerPanel</strong>.</p>
<pre class="python"><span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> ViewerPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        width, height = wx.<span style="color: black;">DisplaySize</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">totalPictures</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span> = height - <span style="color: #ff4500;">200</span>
        Publisher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">updateImages</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;update images&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">slideTimer</span> = wx.<span style="color: black;">Timer</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">slideTimer</span>.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_TIMER</span>, <span style="color: #008000;">self</span>.<span style="color: black;">update</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> layout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Layout the widgets on the panel
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span> = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        btnSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
&nbsp;
        img = wx.<span style="color: black;">EmptyImage</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span>,<span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span> = wx.<span style="color: black;">StaticBitmap</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, wx.<span style="color: black;">ID_ANY</span>,
                                         wx.<span style="color: black;">BitmapFromImage</span><span style="color: black;">&#40;</span>img<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">imageLabel</span> = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">imageLabel</span>, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
&nbsp;
        btnData = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Previous&quot;</span>, btnSizer, <span style="color: #008000;">self</span>.<span style="color: black;">onPrevious</span><span style="color: black;">&#41;</span>,
                   <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Slide Show&quot;</span>, btnSizer, <span style="color: #008000;">self</span>.<span style="color: black;">onSlideShow</span><span style="color: black;">&#41;</span>,
                   <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Next&quot;</span>, btnSizer, <span style="color: #008000;">self</span>.<span style="color: black;">onNext</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> data <span style="color: #ff7700;font-weight:bold;">in</span> btnData:
            label, sizer, handler = data
            <span style="color: #008000;">self</span>.<span style="color: black;">btnBuilder</span><span style="color: black;">&#40;</span>label, sizer, handler<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span>.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>btnSizer, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">CENTER</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">mainSizer</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> btnBuilder<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label, sizer, handler<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Builds a button, binds it to an event handler and adds it to a sizer
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        btn = wx.<span style="color: black;">Button</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label<span style="color: black;">&#41;</span>
        btn.<span style="color: black;">Bind</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">EVT_BUTTON</span>, handler<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>btn, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> loadImage<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, image<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        image_name = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">basename</span><span style="color: black;">&#40;</span>image<span style="color: black;">&#41;</span>
        img = wx.<span style="color: black;">Image</span><span style="color: black;">&#40;</span>image, wx.<span style="color: black;">BITMAP_TYPE_ANY</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># scale the image, preserving the aspect ratio</span>
        W = img.<span style="color: black;">GetWidth</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        H = img.<span style="color: black;">GetHeight</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> W <span style="color: #66cc66;">&gt;</span> H:
            NewW = <span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span>
            NewH = <span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span> <span style="color: #66cc66;">*</span> H / W
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            NewH = <span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span>
            NewW = <span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span> <span style="color: #66cc66;">*</span> W / H
        img = img.<span style="color: black;">Scale</span><span style="color: black;">&#40;</span>NewW,NewH<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">imageCtrl</span>.<span style="color: black;">SetBitmap</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">BitmapFromImage</span><span style="color: black;">&#40;</span>img<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">imageLabel</span>.<span style="color: black;">SetLabel</span><span style="color: black;">&#40;</span>image_name<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Refresh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        Publisher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">sendMessage</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;resize&quot;</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> nextPicture<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Loads the next picture in the directory
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> == <span style="color: #008000;">self</span>.<span style="color: black;">totalPictures</span><span style="color: #ff4500;">-1</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> += <span style="color: #ff4500;">1</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">loadImage</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span><span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> previousPicture<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Displays the previous picture in the directory
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> == <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> = <span style="color: #008000;">self</span>.<span style="color: black;">totalPictures</span> - <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span> -= <span style="color: #ff4500;">1</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">loadImage</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span><span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">currentPicture</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Called when the slideTimer's timer event fires. Loads the next
        picture from the folder by calling th nextPicture method
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">nextPicture</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> updateImages<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Updates the picPaths list to contain the current folder's images
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span> = msg.<span style="color: black;">data</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">totalPictures</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">loadImage</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">picPaths</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onNext<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Calls the nextPicture method
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">nextPicture</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onPrevious<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Calls the previousPicture method
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">previousPicture</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> onSlideShow<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
        Starts and stops the slideshow
        &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        btn = event.<span style="color: black;">GetEventObject</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        label = btn.<span style="color: black;">GetLabel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label == <span style="color: #483d8b;">&quot;Slide Show&quot;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">slideTimer</span>.<span style="color: black;">Start</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3000</span><span style="color: black;">&#41;</span>
            btn.<span style="color: black;">SetLabel</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Stop&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">slideTimer</span>.<span style="color: black;">Stop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            btn.<span style="color: black;">SetLabel</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Slide Show&quot;</span><span style="color: black;">&#41;</span></pre>
<p>Instead of going over every method in this class, we&#8217;ll just take a tour of the highlights. Don&#8217;t worry! The methods that we skip are super easy to grasp and if you just don&#8217;t get it, feel free to comment on this article or ask the question on the <a href="http://wxpython.org/maillist.php">wxPython mailing list</a>. Our first order of business is to look at the init. For the most part, this is a pretty normal initialization, but we also have a couple of goofy lines:</p>
<pre class="python">width, height = wx.<span style="color: black;">DisplaySize</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">self</span>.<span style="color: black;">photoMaxSize</span> = height - <span style="color: #ff4500;">200</span></pre>
<p>What&#8217;s that all about? Well, the idea here is to get the user&#8217;s monitor resolution and then size the application to be just the right height. We want it to fit above the taskbar and below the top of the screen. That is all we&#8217;re doing here. Note that this was tested on Windows 7, so you may need to adjust accordingly for your OS of choice. The <em>loadImage</em> is almost exactly the same as the one we saw in our first example. The only difference is that we use pubsub to tell the frame to resize. Technically, you could also do something like: self.frame.sizer.Fit(self.frame). This is known as bad code. Use the pubsub method instead.</p>
<p>The <em>nextPicture</em> and <em>previousPicture</em> methods are quite similar and should probably be combined, but for now we will leave them as is. In both of these methods, we use currentPicture property and add or subtract as needed to go to the next or previous picture. We also check to see if we&#8217;ve hit the upper or lower bound (i.e. zero or totalPictures) and reset currentPicture appropriately. This allows us to cycle through all the photos forever. Now that we&#8217;ve covered the cycling, we need to figure out how to do a slide show. It&#8217;s actually pretty easy.</p>
<p>First, we create a wx.Timer object and bind it to the <em>update</em> method. When the &#8220;Slide Show&#8221; button is pressed, the timer is started or stopped. If it is started, then the timer will fire every 3 seconds (1000 = 1 second) and that will call the <em>update </em>method, which calls the <em>nextPicture </em>method. As you can see, Python makes everything very simple to do. The rest of the methods are simple utility methods that are called by one of the others.</p>
<h2>Wrapping Up</h2>
<p>I hope you found this interesting. I will be working on expanding this example into something even cooler and I&#8217;ll be sure to share whatever I come up with here. Just the other day, someone on the wxPython IRC channel thought it would be cool if there was a series of articles on simple working wxPython applications. Consider this to be the first (or second if you count <a href="http://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/">wxPyMail</a>). Hopefully I can come up with some other interesting ones.</p>
<p><strong>Note: This code was tested on Windows 7 Home (32-bit), wxPython 2.8.10.1, Python 2.6</strong></p>
<h2>Downloads</h2>
<ul>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/ImageViewer.zip'>ImageViewer.zip</a></li>
<li><a href='http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/ImageViewer.tar'>ImageViewer.tar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

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

