Entries tagged with “wxPython”.


When I was a kid, I was really into secret codes and ciphers. I thought they were all kinds of fun. My mom thought it would be fun to use some of the ciphers I was so enamored with in treasure hunts for special occasions, like birthdays. She would take something like a Cryptograph Wheel and create codes with it that my brother and I would have to decode with our own wheel to find a gift or another clue. We used stuff where numbers would represent letters (a=1, b=2, c=3) or we would use a sliding scale where you move the alphabet one letter over so A=B, C=D, D=E, etc. Sometimes we’d create a code stick where you get a long string of paper and wrap it around a pencil and then write a message of the paper. It’s pretty much impossible to read when it’s unwrapped.

Anyway, I decided to create a silly cipher program with wxPython where I could input a string and have it convert it to something else. I also wanted my program to decode it too. Now you can’t really make a program that can use a Cryptograph Wheel or a code stick, but for number codes or slide scales, that’s extremely easy. (more…)

This week, I needed to figure out how to attach an event handler that would fire when I double-clicked an item (i.e. row) in an ObjectListView widget that was in LC_REPORT mode. For some reason, there isn’t an obvious mouse event for that. There is an EVT_LIST_ITEM_RIGHT_CLICK and an EVT_LIST_ITEM_MIDDLE_CLICK, but nothing for LEFT clicks of any sort. After a bit of searching on Google, I found that I can get it to work by using EVT_LIST_ITEM_ACTIVATED. This will fire when an item is double-clicked and when an item is selected and the user presses ENTER. Here’s a code example:

import wx
from ObjectListView import ObjectListView, ColumnDefn
 
########################################################################
class Results(object):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, tin, zip_code, plus4, name, address):
        """Constructor"""
        self.tin = tin
        self.zip_code = zip_code
        self.plus4 = plus4
        self.name = name
        self.address = address
 
 
########################################################################
class DCPanel(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
 
        mainSizer = wx.BoxSizer(wx.VERTICAL)
 
        self.test_data = [Results("123456789", "50158", "0065", "Patti Jones",
                                  "111 Centennial Drive"),
                          Results("978561236", "90056", "7890", "Brian Wilson",
                                  "555 Torque Maui"),
                          Results("456897852", "70014", "6545", "Mike Love", 
                                  "304 Cali Bvld")
                          ]
        self.resultsOlv = ObjectListView(self, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.resultsOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick)
 
        self.setResults()
 
        mainSizer.Add(self.resultsOlv, 1, wx.EXPAND|wx.ALL, 5)
        self.SetSizer(mainSizer)
 
    #----------------------------------------------------------------------
    def onDoubleClick(self, event):
        """
        When the item is double-clicked or "activated", do something
        """
        print "in onDoubleClick method"
 
    #----------------------------------------------------------------------
    def setResults(self):
        """"""
        self.resultsOlv.SetColumns([
            ColumnDefn("TIN", "left", 100, "tin"),
            ColumnDefn("Zip", "left", 75, "zip_code"),
            ColumnDefn("+4", "left", 50, "plus4"),
            ColumnDefn("Name", "left", 150, "name"),
            ColumnDefn("Address", "left", 200, "address")
            ])
        self.resultsOlv.CreateCheckStateColumn()
        self.resultsOlv.SetObjects(self.test_data)
 
 
########################################################################
class DCFrame(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, parent=None, title="Double-click Tutorial")
        panel = DCPanel(self)
 
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = DCFrame()
    frame.Show()
    app.MainLoop()

Pretty straight-forward, right? I hope it’ll help you if you ever need to know how to do this. This method should work with a ListCtrl as well.

This week I spent some time learning how to add check boxes to the ObjectListView widget in wxPython. If you don’t know, ObjectListView is a 3rd party wrapper for the wx.ListCtrl widget that makes using the ListCtrl much easier. You can read all about it in this older article from the archives. I had a requirement where I needed to have a check box next to each item in the report view of the widget. After some digging on the ObjectListView website, I found an article that sort of explained how to do it. According to the documentation, I could use the CreateCheckStateColumn method or register a column and use InstallCheckStateColumn. In this article, we’ll be focusing on the CreateCheckStateColumn method. (more…)

The other day, I stumbled across a question on StackOverflow asking how to get the children widgets of a BoxSizer. In wxPython, you would expect to call the sizer’s GetChildren() method. However, this returns a list of SizerItems objects rather than a list of the actual widgets themselves. You can see the difference if you call a wx.Panel’s GetChildren() method. Now I don’t ask a lot of questions on the wxPython users group list, but I was curious about this one and ended up receiving a quick answer from Cody Precord, author of the wxPython Cookbook and Editra. Anyway, he ended up pointing me in the right direction and I came up with the following bit of code:
(more…)

People keep on asking fun wxPython questions on StackOverflow. Today they wanted to know how to make “flashing text” in wxPython. That’s actually a pretty easy thing to do. Let’s take a look at some simple code:

import random
import time
import wx
 
########################################################################
class MyPanel(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
 
        self.font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        self.flashingText = wx.StaticText(self, label="I flash a LOT!")
        self.flashingText.SetFont(self.font)
 
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.update, self.timer)
        self.timer.Start(1000)
 
    #----------------------------------------------------------------------
    def update(self, event):
        """"""
        now = int(time.time())
        mod = now % 2
        print now
        print mod
        if mod:
            self.flashingText.SetLabel("Current time: %i" % now)
        else:
            self.flashingText.SetLabel("Oops! It's mod zero time!")
        colors = ["blue", "green", "red", "yellow"]
        self.flashingText.SetForegroundColour(random.choice(colors))
 
 
########################################################################
class MyFrame(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Flashing text!")
        panel = MyPanel(self)
        self.Show()
 
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

Basically all you need is a wx.StaticText instance and a wx.Timer. In this example, the text will “flash” once a second. By flash, we mean it will change colors AND the text itself will change. The original person who made this question wanted to know how to display the time using Python’s time.time() method and they wanted the message to change depending on whether or not the modulus of the time by 2 was equal to zero. I realize that looks a little odd, but I’ve actually used that idea in some of my own code. Anyway, this worked for me on Windows 7 with Python 2.6.6 and wxPython 2.8.12.1.

Note that sometimes the SetForegroundColour method doesn’t work on all widgets across all platforms as the native widget doesn’t always allow the color to be changed, so your mileage may vary.

Today on StackOverflow I saw someone who wanted to know how to drag a file from a wx.ListCtrl onto their Desktop or somewhere else in the file system. They were using the file manager skeleton from zetcode, but couldn’t figure out how to add the DnD portion. After a bit of searching and hacking, I came up with this based on something Robin Dunn mentioned in a forum. (more…)

Today on StackOverflow I saw someone wondering how to bind two functions / methods to the same event in wxPython. It’s really quite easy. Here’s one example: (more…)

Occasionally I’ll see someone on the wxPython users group ask about how to make the wx.Notebook change pages (or tabs) programmatically. So I decided it was about time I figured it out. Here is some code that works for me:

import random
import wx
 
########################################################################
class TabPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent, page):
        """"""
        wx.Panel.__init__(self, parent=parent)
        self.page = page
 
        colors = ["red", "blue", "gray", "yellow", "green"]
        self.SetBackgroundColour(random.choice(colors))
 
        btn = wx.Button(self, label="Change Selection")
        btn.Bind(wx.EVT_BUTTON, self.onChangeSelection)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btn, 0, wx.ALL, 10)
        self.SetSizer(sizer)
 
    #----------------------------------------------------------------------
    def onChangeSelection(self, event):
        """
        Change the page!
        """
        notebook = self.GetParent()
        notebook.SetSelection(self.page)
 
########################################################################
class DemoFrame(wx.Frame):
    """
    Frame that holds all other widgets
    """
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""        
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Notebook Tutorial",
                          size=(600,400)
                          )
        panel = wx.Panel(self)
 
        notebook = wx.Notebook(panel)
        tabOne = TabPanel(notebook, 1)
        notebook.AddPage(tabOne, "Tab 1")
 
        tabTwo = TabPanel(notebook, 0)
        notebook.AddPage(tabTwo, "Tab 2")
 
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
        panel.SetSizer(sizer)
        self.Layout()
 
        self.Show()
 
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()

The main thing to know is that you need to use SetSelection (or ChangeSelection) to force the Notebook widget to change pages. That’s it! This code was tested on Windows 7 with Python 2.7.3 and wxPython 2.9.3.1 (Classic). See also this discussion on Nabble.

This week, I came across a fun Python project named psutil on Google Code. It says it works on Linux, Windows, OSX and FreeBSD. What it does is grab all the running processes and gives you information on them and also gives you the ability to terminate them. So I thought it would be fun to put a GUI on top of it and create my own Task Manager / Process Monitor application with wxPython. If you have a moment, you can come along for the journey as I take you through 4 iterations of my code. (more…)

The other day on StackOverflow I saw someone who was struggling with the Wizard widget from wxPython. The wizard doesn’t allow much customization when it comes to its buttons, so I decided to see how hard it would be to just write my own Wizard. This code is pretty limited, but here’s my first beta version: (more…)