And here's a little hack to get a progress bar updated via a timer...
···
---
import sys
import wx
class TestList(wx.ListCtrl):
"""
A List Ctrl with gauages
"""
def __init__(self, parent, style =
wx.LC_REPORT|wx.LC_VRULES|wx.CLIP_CHILDREN):
wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style = style)
self.parent = parent
# Progress bars
self.progressBars = []
self.clearBars = False
# Columns
self.InsertColumn(0, "Title")
self.InsertColumn(1, "Progress")
self.InsertColumn(2, "Details")
self.SetColumnWidth(0, 200)
self.SetColumnWidth(1, 100)
self.SetColumnWidth(2, 200)
# Some Items...
index = self.InsertStringItem(sys.maxint, "The First Item")
self.SetStringItem(index, 1, "0")
self.SetStringItem(index, 2, "Nothing")
index = self.InsertStringItem(sys.maxint, "The Second Item")
self.SetStringItem(index, 1, "25")
self.SetStringItem(index, 2, "its a start")
index = self.InsertStringItem(sys.maxint, "The Third Item")
self.SetStringItem(index, 1, "50")
self.SetStringItem(index, 2, "Half way")
index = self.InsertStringItem( sys.maxint, "The Fourth Item")
self.SetStringItem(index, 1, "75")
self.SetStringItem(index, 2, "Almost...")
index = self.InsertStringItem(sys.maxint, "The Last Item")
self.SetStringItem(index, 1, "100")
self.SetStringItem(index, 2, "Complete")
index = self.InsertStringItem(sys.maxint, "Some progress...")
self.SetStringItem(index, 1, "0")
self.SetStringItem(index, 2, "Working")
self.timeout = 200
self.working_rank = 1 # column with the gauge
self.working_index = index
self.working_progress = 0
self.timer = wx.PyTimer(self.OnNotify)
self.timer.Start(self.timeout)
self.visibleIndexes = []
# Events
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind (wx.EVT_LIST_COL_DRAGGING, self.OnPaint)
self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnPaint)
self.Bind(wx.EVT_SCROLL, self.OnPaint)
def OnNotify(self):
self.working_progress += 1
if self.working_progress > 100:
self.working_progress = 0
print self.working_progress
row = self.working_index
rank = self.working_rank
self.SetStringItem(row, rank, str(self.working_progress))
if row in self.visibleIndexes:
bar = self.progressBars[row]
print bar
bar.SetValue(self.working_progress)
self.timer.Start(self.timeout)
def OnPaint(self, event=None):
"""
Handles the EVT_PAINT event
"""
print "OnPaint"
self._OnPaintBars()
if event:
event.Skip()
def _OnPaintBars(self):
"""
Actual drawing of progress bars
"""
# General list info
rank = 1 # the column with the gauges
itemCount = self.GetItemCount() # number of items
# No progress column or no items
if rank == -1 or not itemCount:
[p.Destroy() for p in self.progressBars]
del self.progressBars [:]
return False
if self.clearBars:
self.clearBars = False
[p.Destroy() for p in self.progressBars]
del self.progressBars[:]
# Indexes
topItem = self.GetTopItem() # top
self.visibleIndexes = range(topItem, topItem +
min(self.GetCountPerPage()+1, itemCount)) # to show
# Make sure no extra bars
while len(self.progressBars) > itemCount:
progressBar = self.progressBars.pop()
progressBar.Destroy()
# Make sure enough bars
while len(self.progressBars) < itemCount:
progressBar = self._getProgressBar()
self.progressBars.append(progressBar)
# Update bars positions, size and value
rect = self.GetItemRect(topItem)
size = (self.GetColumnWidth(rank)-4, rect[3]-4)
x = rect[0] + sum([self.GetColumnWidth(i) for i in range(0, rank)]) + 2
# Compensate for differences when ListCtrl uses a native
# scrolled list vs a scrolled window containing a list
if self == self.GetMainWindow():
y = rect[1] + 2
else:
y = 0
inc = rect[3]
for row in range(itemCount):
if row in self.visibleIndexes:
bar = self.progressBars[row]
if bar.GetPosition () != (x, y):
if wx.Platform != "__WXMSW__":
bar.Hide()
bar.SetPosition((x, y))
bar.SetSize(size)
bar.SetValue(self.getItemValue(row, rank))
bar.Show()
y += inc
else:
self.progressBars[row].Hide()
return True
def _getProgressBar(self):
return wx.Gauge(self.GetMainWindow(), -1, 100, style = wx.NO_BORDER)
def getItemValue(self, row, rank):
"""
Just for testing, this method returns the value of an item
"""
if row == self.working_index:
return self.working_progress
return row*25
class TestFrame( wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
self.list = TestList(self)
if __name__ == "__main__":
app = wx.App(0)
f = TestFrame()
f.Show()
app.MainLoop()