Click here to Skip to main content
15,884,237 members
Articles / Operating Systems / Linux
Tip/Trick

Creating a Custom wxPython Progress Bar Widget

Rate me:
Please Sign up or sign in to vote.
4.60/5 (2 votes)
17 Oct 2013CPOL2 min read 20K   187   1   3
A simple alternative progress bar or gauge in wxPython
Image 1

Introduction

Occasionally, when working with wxPython, you run up against the coding limitations of the provided widgets. For instance, in the wx.Gauge widget, color selection isn't customizable. If this is an option you'd like to explore, consider the code snippet below.

Background

My personal frustration began when I wished to indicate the progress of a process and also indicate if the process was encountering an error or was working as expected. Also, the behavior of wx.Gauge differed somewhat when viewed under Linux and when viewed under Windows. After fruitless searches of the internet for a solution, I came up with the "bright" idea that I could write my own progress bar widget. Surprisingly, this ended up being a very simple task.

Using the Code

The simplest approach to using this progress bar is to cut and paste the code snippet into your pre-existing wxPython code. If you are interested in experimenting with a crude wxPython application, I am including a very basic GUI interface for your perusal. Please modify the code as necessary to fit your requirements.  

 ########################################################
#
#  A simple color-selectable Progress Bar widget
#
#  Member functions are as follows:
#
#   __init__(self,parent,id,position(0,0),size=(20,100),progress)
#
#   SetProgress(self,progress,errorflag)  
#
#       Sets the progress from 0 to 100 as a percentage, if error
#       is non-zero, the progress bar changes from a defined
#       normal color to a defined error color
#
#   SetBGColor(self,color)
#
#       Sets the background color of the progress bar.
#
#   SetProgColor(self,color)
#
#       Sets the color that the progress bar will normally be
#       displayed.
#
#   SetErrColor(self,color)
#
#       Sets the color of the progress bar when an error occurs.
#
#   GetProgress(self)
#
#       Returns the current progress value from the progress
#       bar widget.
#
########################################################
class MyProgBar(wx.Panel):
    def __init__(self,parent,id=-1, position=(0,0),size=(20,100),prog=50):
        self.myWidth = size[0]
        self.myHeight = size[1]
        self.myprogress = 0
        self.myerror = 0
        self.BasePanel = wx.Panel(parent,id,position,size,wx.BORDER)
        self.ProgPanel = wx.Panel(self.BasePanel,-1,(0,0),(1,self.myHeight))
        self.bgcolor   = wx.WHITE
        self.progcolor = wx.GREEN
        self.errcolor  = wx.RED
        self.BasePanel.SetBackgroundColour(self.bgcolor)
        self.SetProgress(0)
    
    def SetProgress(self,prog=50,error=0):
        width = self.myWidth*prog/100
        self.myerror = error
        if(prog<0):
            prog = 0
        if(prog>100):
            prog = 100
        self.myprogress = prog
        width = self.myWidth*prog/100
        if(width<1):
            width = 1
        if(error):
            self.ProgPanel.SetBackgroundColour(self.errcolor)
        else:
            self.ProgPanel.SetBackgroundColour(self.progcolor)
        self.ProgPanel.SetSize((0,0))
        self.ProgPanel.SetSize((width,self.myHeight))
        
    def SetBGColor(self,color=wx.WHITE):
        self.bgcolor = color
        self.BasePanel.SetBackgroundColour(color)
        
    def SetProgColor(self,color=wx.GREEN):
        self.progcolor = color
        self.ProgPanel.SetBackgroundColour(color)
        
    def SetErrColor(self,color=wx.RED):
        self.errcolor = color
        
    def GetProgress(self):
        return self.myprogress 

Using the widget is quite simple. You can attach it to a pre-existing wx.Panel as shown below. The background color, progress bar color, and error color can be customized here as well. Theoretically, the colors can be changed any time you feel the need, but that is beyond the scope of this tip. Have at!

Use in your initializer as follows:

...
self.panel = wx.Panel(parent,id,(0,0),(500,500))
self.progress = wx.MyProgBar(self.panel,-1,(50,50),(128,20))
self.progress.SetBGColor(wx.WHITE)
self.progress.SetProgColor(wx.GREEN)
self.progress.SetErrColor(wx.RED)
...

Use the progress bar as follows:

self.progress.SetProgress(50)  # Sets progress to 50%

..or..

self.progress.SetProgress(99,1) #sets progress to 99& but indicates an error.

Points of Interest

Essentially, this progress bar consists of two cascaded panels. A background panel called BasePanel, and a progress panel (the thing which indicates the progress), which is a child of the background panel. Panels can have their colors set at any time, so that's what is being done here. Sizing the progress panel had one gotcha to it. The panel had to be pre-sized to zero width to clear out the previously painted panel before setting the new size of the progress bar. This can be seen in the code snippet below:

self.ProgPanel.SetSize((0,0))
self.ProgPanel.SetSize((width,self.myHeight))

History

  • Version 1.0: Wednesday, October 16, 2013
  • Version 1.1: Thursday, October 17, 2013 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Programmer of disk drive manufacturing equipment (servo track writers) and SSD test equipment. I write code mostly in C and C++, and work on both Software (PC) and firmware (various micro-controllers). The firmware work has also included assembly language. Done a lot of coding for a lot of years. Recently became addicted to python and wxPython, and am getting far more linux experience than I ever thought possible. Very fun and refreshing.

Comments and Discussions

 
GeneralMy vote of 3 Pin
freeluna17-Oct-13 10:17
professionalfreeluna17-Oct-13 10:17 
QuestionJust a thought but Pin
Sacha Barber16-Oct-13 23:08
Sacha Barber16-Oct-13 23:08 
AnswerRe: Just a thought but Pin
freeluna17-Oct-13 9:09
professionalfreeluna17-Oct-13 9:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.