Updated version (with easy color settings and more fast):
I am not sure how to attach the source without starting a new topic
#wx gauge: background is now settable to any color, as well as the
foreground.
import numpy, colorsys #didnt yet figure it out to do with wx image
buffers
import wx
import time, random
from wx.lib.colourdb import *
from wx.lib.embeddedimage import PyEmbeddedImage
green = PyEmbeddedImage( #captured image data of wx.Gauge,
converted with img2py
"iVBORw0KGgoAAAANSUhEUgAAABcAAAAMCAIAAAAGWbGvAAAAA3NCSVQICAjb4U/
gAAABIUlE"
"QVQokZWSwUoDMRCGv3+SrRUq9OALePPgE/jE
+i6Cd19AwYOCVLrNZsZDtstui4cOIUzgnz/f"
"JKOnn+eyKVu2N2yANdcdmQvD3jfvl9acR6bY4F6i9lEBKAMhaaHSWbLM8+++p
+yG0C4KsIqr"
"TEIgLYqnhc5Ncyllf
+hTdF4FFDwpCbCjyKChnbho5uJO9VpqTa2jGJzAwDXq4silRSVAjDy6"
"f3n8+P469LUMDtTqLkiQtNhNJDAwjZhtlxAZYYZMZgAeMhGTeqzRDGfJ1VwsK2VLNQIDMHdm"
"LDZjsf9ZLCt11gXNRK7QUd1aaF7tqJnLnIWurtYJwypAreGa3ZnOEU46ApEfPu9eb9+6Lg3F"
"AfeI9rsTdrOYnmM+AYxD8Ad6BmPw30s6zQAAAABJRU5ErkJggg==")
grey = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAQCAIAAACgHXkXAAAAA3NCSVQICAjb4U/
gAAAAt0lE"
"QVQYlYVPSwqFMBBzPuDWjTu9hpf2DF7CW4ggioKtTvAtBqq8J7wswjTptAnt+973/
TAM2Ruo"
"67q6rsuyFJFbJfJBl2VpmibPc2b+3VYAx3HEGJ97iRVACMHM/JwMhwI4zzOEQET
+fvKyLFMz"
"AxBjZGZXfXBWANu2jeNIRCLCX3itm/
DPBuBx0t8JzKxm5tMTdwgA13U9byRPRBTAl5RYVbUo"
"inmeq6p69r6rr+vatu00Ta/JP6f5Vbmj8yjIAAAAAElFTkSuQmCC")
#conversion from PyEmbeddedImage is costly in time, but only used on
Init
BaseCol =
["Go","G2","R1","R2","B1","B2","Y1","Y2","P1","P2","P1","P2","P1","P2","P1","P2"]
#ignore this, for testing only
ID_Button, startID =[],0
for x in range(30):
val = wx.NewId()
if startID== 0: startID= val
ID_Button.append(val)
endID = val
#still hard coded ID's: still I do not know how (and why) to make the
code more readable
# ... without them and it works for me fine this way
ID_testFrame = wx.NewId()
class startCtrl(wx.Panel):
def __init__(self, parent, frame, id=wx.ID_ANY,
pos=wx.DefaultPosition,
size=wx.DefaultSize, mgr=None):
wx.Panel.__init__(self, parent, id, pos, size)
self.size = size
sizer = wx.GridBagSizer(vgap=0, hgap=0)
#some toolbar buttons for selecting the colors
self.bar= wx.ToolBar(self, -1, wx.DefaultPosition,
wx.DefaultSize,
wx.TB_NODIVIDER | wx.TB_HORZ_TEXT)
self.bar.SetToolBitmapSize(wx.Size(48,48))
symbol = wx.ArtProvider_GetBitmap(wx.ART_INFORMATION)
symbol1 = grey.GetImage()
symbol1.Scale(10, 10)
#for x in range(len(BaseCol)):
for x in range(1):
caption = BaseCol[x]
id = ID_Button[x]
self.bar.AddLabelTool(id,caption, symbol)
self.bar.Realize()
sizer.Add(self.bar, pos=(0,0))
self.ePanel=aPanel(self,size=(800,500))
sizer.Add(self.ePanel, pos=(1,0))
self.SetSizer(sizer)
self.Fit()
class aPanel(wx.Panel): #this is test class for the new gauge,
obviously needs some init parameters
def __init__(self, parent, ID=-1, pos=wx.DefaultPosition,
size=(100, 25),
type=1, mainCaption="",
style=wx.NO_FULL_REPAINT_ON_RESIZE):
wx.Panel.__init__(self, parent, ID, pos, size,
wx.RAISED_BORDER)
self.SetMinSize(size)
iSizeX, iSizeY = 620, 30
self.iSizeX, self.iSizeY = iSizeX, iSizeY
width, height = self.iSizeX, self.iSizeY
self.BgColor = self.getColor(colorStr="Purple", darken = 5)
self.FgColor = self.getColor(colorStr="Purple")
#see function for parameters, you can use colors from the wx
colordb (very approx), local color and or specify the
#hue, also you can darken the color
self.updatedYet = False
array = numpy.zeros( (height, width, 3),'uint8') #produce
background
bgCol = 202
array[:,:,] = (bgCol,bgCol,bgCol)
xI = grey.GetImage()
topRows, bottomRows, lenRows = 7, 8, 10
array = self.fillRows(array, xI, topRows, bottomRows, lenRows)
array = self.fillCols(array, lenRows, self.iSizeX)
#put in buffer
self.nI = wx.EmptyImage(width,height)
self.nI.SetData(array.tostring())
self.bI = self.nI.ConvertToBitmap()
#create the foreground progressionbar
self.arrayP = array[:] #this is the data
buffer
#self.gI = green.GetImage()
topRows, bottomRows, lenRows = 6, 5, 23 #hard coded img2py
image, needs work
self.arrayP= self.fillRows(self.arrayP, green.GetImage(),
topRows, bottomRows, lenRows, bg=False)
#bindings
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.OnSize(None)
def fillRows(self, array, xI, topRows, bottomRows, lenRows,
bg=True):
lenRowsX3 = lenRows*3 # put colors strings into
numpy array, please show me a quicker way
for tRows in range(topRows):
idxBeg = tRows*lenRowsX3
array[tRows,:lenRows] = self.colorAdjust(xI.GetData()
[idxBeg:idxBeg+lenRowsX3], bg)
numMidRows = self.iSizeY - topRows - bottomRows
idxBeg = (tRows+1) * lenRowsX3
for x in range(numMidRows):
array[tRows+x+1,:lenRows] = self.colorAdjust(xI.GetData()
[idxBeg:idxBeg + lenRowsX3],bg)
for bRows in range(bottomRows):
idxBeg = (bRows + topRows+1) * lenRowsX3
idxArray = tRows + numMidRows + bRows + 1
array[idxArray,:lenRows] = self.colorAdjust(xI.GetData()
[idxBeg: idxBeg + lenRowsX3],bg)
return array
def fillCols(self, array, lenRows, endCol, init=True):
if init or self.updatedYet==False: #to speed things up: this
is the place
for rows in range(self.iSizeY): # append the middle and
end colums
array[rows,lenRows:endCol-lenRows
+1,]=array[rows,lenRows-1]
array[rows,endCol-lenRows:endCol]=array[rows,
0:lenRows][::-1]
return array
else:
for rows in range(self.iSizeY): # append the end colums
only (works only when continously)
array[rows,endCol-lenRows:endCol]=array[rows,
0:lenRows][::-1]
return array
def colorAdjust(self,string,bg):
newList = []
for x in range(0,len(string),3):
if bg:
col = ord(string[x])
if self.BgColor[0] < 0 or self.BgColor[0] > 360:
newList.append([col,col,col])
else: #use hue
sTmp = 1.892 * col -222 #increase the small
differences
h,s,v = float(self.BgColor[0])/360, float(sTmp)/
255,self.BgColor[1]
r,g,b = [int(c*255) for c in
colorsys.hsv_to_rgb(h,s,v)]
newList.append([r,g,b])
else:
col1, col2, col3 = ord(string[x]), ord(string[x+1]),
ord(string[x+2])
r,g,b = col1,col2,col3
h,s,v = colorsys.rgb_to_hsv(float(r)/255,float(g)/
255,float(b)/255)
h = float(self.FgColor[0])/360
v = float(self.FgColor[1]*v)
r,g,b = [int(c*255) for c in
colorsys.hsv_to_rgb(h,s,v)]
newList.append([r,g,b])
return newList
def getColor(self, colorStr="", Hue=-1, darken=0):
colBgDict = {"Yellow":60,"Orange":40,"Red":0, "Pink":
320,"Purple":280,"Blue":240,
"Aqua":180,"Lime": 120} #some local
colors
if darken<0 or darken>100: darken =0
darkValue = 1 - float(darken)/100
if Hue>=0 and Hue<360: return [Hue,darkValue] #Hue
is specified: do nothing
if colorStr in colBgDict.keys(): return
[colBgDict[colorStr],darkValue] #local colors
tmp = getColourList()
if colorStr in tmp: #for now only extract the Hue and V
value
position = tmp.index(colorStr)
name, r,g,b = getColourInfoList()[tmp.index(colorStr)]
h,s,v = colorsys.rgb_to_hsv(float(r)/255,float(g)/
255,float(b)/255)
if darken == 0: darkValue = v
Hue = int(h*360)
return [Hue, darkValue] #negative Hue means default BG color
def UpdateImage(self, updateTo=100, col=0):
if updateTo > self.iSizeX : updateTo = self.iSizeX
lenRows = 23
self.arrayP = self.fillCols(self.arrayP, lenRows, updateTo,
init=False)
self.nI.SetData(self.arrayP.tostring())
self.bI = self.nI.ConvertToBitmap()
self._Buffer = self.bI
self.UpdateDrawing()
self.updatedYet = True
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self._Buffer)
def OnSize(self, event):
self.Width, self.Height = self.GetClientSizeTuple()
self._Buffer = self.bI
self.UpdateDrawing()
def Draw(self, dc):
pass
def UpdateDrawing(self):
dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
self.Draw(dc)
class testFrame(wx.Frame):
#handler class all toolbar events are ment to be used here
def __init__(self, parent, id=-1, title=""):
wx.Frame.__init__(self, parent, id)
self.Maximize()
self.ctrl = startCtrl(self, self)
self.Bind(wx.EVT_MENU_RANGE,
self.OnButton,id=startID,id2=endID)
self.counter = 100
def OnButton(self,event):
xid = event.GetId()
butNr = xid - startID
if butNr >= 0 and butNr < 20:
col = butNr
self.counter = 60
for y in range(400):
self.ctrl.ePanel.UpdateImage(updateTo=self.counter,
col=col)
self.counter+=3
#time.sleep(0.01)
if butNr == 1: pass
#self.ctrl.pBar.update(100)
def OnExit(self, event):
self.Close()
···
#----------------------------------------------------------------------------
class testApp(wx.App):
def __init__(self, name):
self.name = name
wx.App.__init__(self, redirect=False)
def OnInit(self):
frame = testFrame(None, ID_testFrame)
frame.Maximize()
frame.Show()
return True
if __name__ == '__main__':
app = testApp('test')
app.MainLoop()