different colors on wxgauge look a like

Hi everyone,
After asking a question about a wxGauge with custom color (which doesn’t exist with the same look and feel), I submitted some really bad Python code here implementing the basic frame of a wxGauge with the BG/FG color as desired. Since I am a newbie at Python, the code obviously was really bad and slow. Today I had some empty hours and thanks to Robin Dunn I cleaned up my code (sorry: now it is shorter but with a lot of comments still), and thanks to Chris Barker for his hints, all previous problems (being too slow) are solved in the code attached (e.g. the update function went from >>100 lines to just 2).

However I could use some help with:

  1. reading the img2py data into a
    numpy really fast (sorry Chris: I found this way easier than using the image buffers) , so that the gauge can change colors on processing (with
    a single BG/FG color this is not a problem)

  2. mapping the values of the screencaptured and img2py data background smartly into new colors using the colorsdb (this is very doable, since in HSV only V variates),

  3. mapping the values of the screencaptured progressionbar (green) into new FG colors using colorsdb (more complex)

  4. stripping columns of the initial progressbar while maintaining its look and feel

…and more. Any help is really appreciated.

TIA,
Samuel

learningWxPython002.py (9.43 KB)

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()

Your email client will allow you to attach a file regardless of it
being a new message or a reply. As it is now, you can’t copy/paste to a
text file due to the line breaks added by google groups

···

On 18 March 2010 09:52, samuel en samuel110011@gmail.com wrote:

Updated version (with easy color settings and more fast):

I am not sure how to attach the source without starting a new topic

[…]

Your email client will allow you to attach a file regardless of it being a
new message or a reply. As it is now, you can't copy/paste to a text file
due to the line breaks added by google groups

Obviously, but what if there is nothing to reply to (I don't receive
message in my email client nor do I want too)?

well your 2nd message was sent as a reply to the first one, or at least google has grouped them together

···

On 18 March 2010 17:40, samuel en samuel110011@gmail.com wrote:

Your email client will allow you to attach a file regardless of it being a

new message or a reply. As it is now, you can’t copy/paste to a text file

due to the line breaks added by google groups

Obviously, but what if there is nothing to reply to (I don’t receive

message in my email client nor do I want too)?

I am sorry, but I fail to see the point you are trying to make in your
comments.

When logged in in google with a gmail account, you can reply to a
message in this groups by the webInterface , as I am doing now, but
you can't include an attachment.

Also I don't understand why posting directly into Google is such a
problem: ok: there is the linebreaks issue, but it looks trivial to me
to write a small Python script to correct this.

In that case I'd suggest uploading the script as a file on f.e. 4shared.com and putting a link in your reply.
You are asking for help from more experienced people (that doesn't include me though) so it makes sense to try to enable them to help you in the least time for both them and you.
Pacific Morrowind

···

On 19/03/2010 4:54 AM, samuel en wrote:

I am sorry, but I fail to see the point you are trying to make in your
comments.

When logged in in google with a gmail account, you can reply to a
message in this groups by the webInterface , as I am doing now, but
you can't include an attachment.

Also I don't understand why posting directly into Google is such a
problem: ok: there is the linebreaks issue, but it looks trivial to me
to write a small Python script to correct this.

This helps. Thanks. Will do so. For the rest: anyone reading the code:
forget about it. I will post a much better and faster version with
gradients and fully implemented wx colordb colors soon.

···

On 19 mrt, 13:28, Pacific Morrowind <pacificmorrow...@gmail.com> wrote:

In that case I'd suggest uploading the script as a file on f.e.
4shared.com and putting a link in your reply.
You are asking for help from more experienced people (that doesn't
include me though) so it makes sense to try to enable them to help you
in the least time for both them and you.
Pacific Morrowind