Category Archives: Cross-Platform

This article will be about a topic that can be used across platforms, such as Linux, Windows and Mac.

wxPython: Learning about TreeCtrls

The wxPython GUI toolkit comes with many widgets. A common control is a tree widget. wxPython has several different tree widgets, including the regular wx.TreeCtrl, the newer DVC_TreeCtrl and the pure Python variants, CustomTreeCtrl and HyperTreeList. In this article, we will focus on the regular wx.TreeCtrl and learn the basics of how to create and use one.

Creating a Simple Tree

Creating a TreeCtrl is actually quite easy. The wxPython demo has a fairly complex example, so I wasn’t able to use it here. Instead I ended up taking the demo example and stripping it down as much as I could. Here’s the result:

import wx
 
class MyTree(wx.TreeCtrl):
 
    def __init__(self, parent, id, pos, size, style):
        wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
 
 
class TreePanel(wx.Panel):
 
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
 
        self.tree = MyTree(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize,
                           wx.TR_HAS_BUTTONS)    
 
        self.root = self.tree.AddRoot('Something goes here')
        self.tree.SetPyData(self.root, ('key', 'value'))
        os = self.tree.AppendItem(self.root, 'Operating Systems')
        self.tree.Expand(self.root)
 
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tree, 0, wx.EXPAND)
        self.SetSizer(sizer)
 
 
class MainFrame(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title='TreeCtrl Demo')
        panel = TreePanel(self)
        self.Show()
 
 
if __name__ == '__main__':
    app = wx.App(redirect=False)
    frame = MainFrame()
    app.MainLoop()

In this example, we create a subclass of wx.TreeCtrl that doesn’t do anything. Then we create a panel subclass where we instantiate the tree and add a root and sub-item. Finally we create the frame that holds the panel and run the application. You should end up with something that looks similar to the following:

This is a pretty boring example, so let’s make something a bit more interesting. Continue reading wxPython: Learning about TreeCtrls

Getting Started with pywebview

I stumbled across the pywebview project a couple of weeks ago. The pywebview package “is a lightweight cross-platform wrapper around a webview component that allows to display HTML content in its own native GUI window.” It uses WebKit on OSX and Linux and Trident (MSHTML) on Windows, which is actually what wxPython’s webview widget also does. The idea behind pywebview is that it provides you the ability to load a website in a desktop application, kind of Electron.

While pywebview claims it “has no dependencies on an external GUI framework”, on Windows it requires pythonnet, PyWin32 and comtypes installed. OSX requires “pyobjc”, although that is included with the default Python installed in OSX. For Linux, it’s a bit more complicated. On GTK3 based systems you will need PyGObject whereas on Debian based systems, you’ll need to install PyGObject + gir1.2-webkit-3.0. Finally, you can also use PyQt 4 or 5.

You can use Python micro-web frameworks, such as Flask or bottle, with pywebview to create cool applications using HTML5 instead of Python.

To install pywebview itself, just use pip:


pip install pywebview

Once installed and assuming you also have the prerequisites, you can do something like this:

import webview
 
webview.create_window('My Web App', 'http://www.mousevspython.com')

This will load the specified URL in a window with the specified title (i.e. the first argument). Your new application should end up looking something like this:

Continue reading Getting Started with pywebview

wxPython Phoenix Alpha Release

The wxPython project made a major announcement over the weekend in releasing an alpha version of the new wxPython “Phoenix” package to the Python Packaging Index (PyPI). wxPython is a major cross-platform desktop graphics user interface toolkit for Python. It wraps wxWidgets and is one of the major competitors to PyQt. All new releases of wxPython will be going to PyPI in the future. You can get a copy directly here:

It should also be noted that wxPython is now being distributed as a Python wheel and a tarball. What this means is that you can now install wxPython with pip:

pip install wxPython

If you want to stay on the bleeding edge and use a daily snapshot build, then you do the following:

pip install --pre --find-links http://wxpython.org/Phoenix/snapshot-builds/ wxPython

I’ve been using the Phoenix version of wxPython for over a year and so far it has worked great! You can read more about the differences between it and Classic here:

Python 101: All About Dictionaries

The Python programming language has several built-in types that it supports. One of my favorites is the dictionary. A dictionary is a mapping object maps hashable values to arbitrary objects (source). Other languages call dictionaries “hash tables”. They are mutable objects that you can change whenever you want to, unlike tuples. A dictionary’s keys must be hashable or immutable, which means that you cannot use a list or another dictionary as a key. Note that dictionaries before Python 3.6 are not ordered. In Python 3.6, they changed the dict’s implementation so that it is now ordered, although there is a warning mentioned that you should not rely on it being ordered. What this means is that when you iterate over a dictionary, you may not extract the values in the same order that you inserted them except in Python 3.6 and potentially future versions of Python.

In this article, we will take some time learning about some of the many things you can do with a dictionary.


Creating Dictionaries

A dictionary is a key:value pair. In Python, these key:value pairs are enclosed inside of curly braces with commas between each pair. Creating dictionaries in Python is really easy. Here are the three ways to create a dictionary:

>>> my_dict = {}
>>> my_other_dict = dict()
>>> my_other_other_dict = {1: 'one', 2: 'two', 3: 'three'}

In the first example, we create an empty dictionary by just assigning our variable to a pair of empty curly braces. You can also create a dictionary object by calling Python’s built-in dict() keyword. I have seen some people mention that calling dict() is slightly slower than just doing the assignment operator. The last example shows how to create a dictionary with some predefined key:value pairs. You can have dictionaries that contain mappings of various types, including mapping to functions or objects. You can also nest dictionaries and lists inside your dictionaries!

Continue reading Python 101: All About Dictionaries

How to Run Python Tests “Continuously” While Coding

Last week I was doing some Test Driven Development training and overheard someone mention another programming language that had a test runner that you could set up to watch your project directory and run your tests when the files changed. I thought that was a neat idea. I also thought I could easily write my own Python script to do the same thing. Here’s a pretty rough version:

import argparse
import os
import subprocess
import time
 
 
def get_args():
    parser = argparse.ArgumentParser(
        description="A File Watcher that executes the specified tests"
        )
    parser.add_argument('--tests', action='store', required=True,
                        help='The path to the test file to run')
    parser.add_argument('--project', action='store', required=False,
                        help='The folder where the project files are')
    return parser.parse_args()
 
 
def watcher(test_path, project_path=None):
    if not project_path:
        project_path = os.path.dirname(test_path)
 
    f_dict = {}
 
    while True:
        files = os.listdir(project_path)
        for f in files:
            full_path = os.path.join(project_path, f)
            mod_time = os.stat(full_path).st_mtime
            if full_path not in f_dict:
                f_dict[full_path] = mod_time
            elif mod_time != f_dict[full_path]:
                # Run the tests
                cmd = ['python', test_path]
                subprocess.call(cmd)
                print('-' * 70)
                f_dict[full_path] = mod_time
 
        time.sleep(1)
 
 
def main():
    args = get_args()
    w = watcher(args.tests, args.project)
 
if __name__ == '__main__':
    main()

To run this script, you would need to do something like this:


python watcher.py --test ~/path/to/tests.py --project ~/project/path

Continue reading How to Run Python Tests “Continuously” While Coding

wxPython Cookbook Writing Update: Beta Version Available

I am happy to announce that I now have all the chapters for my latest book, wxPython Cookbook, ready to be checked out. I still consider the book to be in beta mode as I need to go through each chapter and check them over as much as possible this month, but I am also pretty confident that the book is over 90% complete. Some chapters still need a screenshot or two added and I also plan to add another chapter or two as well.

For those of you who like raw data, there are currently 51 recipes in the book + the introduction and installation chapters. There are over 300 pages of content, which is more than either of my previous books!

I hope to do some polishing this week by adding the missing screenshots and also writing a brand new chapter. I am also hoping to get some of the code examples into Github this week. I do apologize for the delay in getting that done. Life has been really crazy on my end.

You can get early access to the book on Leanpub and Gumroad. You will also receive the final product + updates if you purchase the book from either of those websites. You can also check out the original Kickstarter campaign to learn more about the book.

Thanks again for all your support!

wxcookbook_small

Creating Graphs with Python and GooPyCharts

Over the summer, I came across an interesting plotting library called GooPyCharts which is a Python wrapper for the Google Charts API. In this article, we will spend a few minutes learning how to use this interesting package. GooPyCharts follows syntax that is similar to MATLAB and is actually meant to be an alternative to matplotlib.

To install GooPyCharts, all you need to do is use pip like this:

pip install gpcharts

Now that we have it installed, we can give it a whirl!


Our First Graph

Using GooPyCharts to create a chart or graph is extremely easy. In fact, you can create a simple graph in 3 lines of code:

>>> from gpcharts import figure
>>> my_plot = figure(title='Demo')
>>> my_plot.plot([1, 2, 10, 15, 12, 23])

If you run this code, you should see your default browser pop open with the following image displayed:

gpchart_simple

You will note that you can download the figure as a PNG or save the data that made the chart as a CSV file. GooPyCharts also integrates with the Jupyter Notebook.

Continue reading Creating Graphs with Python and GooPyCharts

How to Create a Diff of an Image in Python

For the past couple of years, I’ve been writing automated tests for my employer. One of the many types of tests that I do is comparing how an application draws. Does it draw the same way every single time? If not, then we have a serious problem. An easy way to check that it draws the same each time is to take a screenshot and then compare it to future versions of the same drawing when the application gets updated.

The Pillow library provides a handy tool for this sort of thing that is called ImageChops. If you don’t already have Pillow, you should go install it now so you can follow along with this short tutorial.


Comparing Two Images

The first thing we need to do is find two images that are slightly different. You can create your own by using burst mode on your camera and taking a bunch of photos of animals as they move, preferably while using a tripod. Or you can take an existing photo and just add some kind of overlay, such as text. I’m going to go with the latter method. Here is my original photo of Multnomah Falls in Oregon:

multnomah_falls

Continue reading How to Create a Diff of an Image in Python

An Intro to the Python Imaging Library / Pillow

The Python Imaging Library or PIL allowed you to do image processing in Python. The original author, Fredrik Lundh, wrote one of my favorite Python blogs when I first started learning Python. However PIL’s last release was way back in 2009 and the blog also stopped getting updated. Fortunately, there were some other Python folks that came along and forked PIL and called their project Pillow. The Pillow project is a drop-in replacement for PIL that also supports Python 3, something PIL never got around to doing.

Please note that you cannot have both PIL and Pillow installed at the same time. There are some warnings in their documentation that list some differences between PIL and Pillow that get updated from time to time, so I’m just going to direct you there instead of repeating them here since they will likely become out of date.


Install Pillow

You can install Pillow using pip or easy_install. Here’s an example using pip:

pip install Pillow

Note that if you are on Linux or Mac, you may need to run the command with sudo.


Opening Images

jelly

Pillow makes it easy to open an image file and display it. Let’s take a look:

from PIL import Image
 
image = Image.open('/path/to/photos/jelly.jpg')
image.show()

Here we just import the Image module and ask it to open our file. If you go and read the source, you will see that on Unix, the open method saves the images to a temporary PPM file and opens it with the xv utility. On my Linux machine, it opened it with ImageMagick, for example. On Windows, it will save the image as a temporary BMP and open it in something like Paint.

Continue reading An Intro to the Python Imaging Library / Pillow

Restarting a Twisted Reactor

I recently started using twisted a couple of weeks ago. For those who don’t know, twisted is “event-driven networking engine written in Python”. The learning curve is pretty steep if you’ve never done asynchronous programming before. During the project I was working on, I ran into a condition where I thought I needed to restart the twisted reactor. According to everything I found online, restarting the reactor is not supported. But I can be stubborn so I tried to find a way anyway.

Restarting a Twisted Reactor

Let’s start by creating a pretty standard twisted server. We’ll subclass LineReceiver which basically makes a TCP server that accepts full lines of text, although it can also do raw data too. Let’s take a look at the code:

Continue reading Restarting a Twisted Reactor