SetBackgroundColour on Panels

1,732 views
Skip to first unread message

Sheepherd

unread,
Aug 23, 2009, 7:42:07 AM8/23/09
to wxPython-users
Well this is a little bit complex.

ive got following function to create several panels and statictexts.
all of them are enumrated and working fine.

def createPanels(self, num):
x = 0
font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
font.SetPointSize(30)
for num in range(num):
y = num % 9
if (num > 0) and (num % 9) == 0:
x += 1
self.panelname = 'panel{0}'.format(num)
self.panelname = wx.Panel(self.panel, wx.ID_ANY,
style=wx.SIMPLE_BORDER)
textname = 'static{0}'.format(num)
textname = wx.StaticText(self.panelname, wx.ID_ANY, str(num
+1))
textname.SetFont(font)
self.sizer.Add(self.panelname, (x, y), (1, 1),
wx.EXPAND | wx.ALL, border=0)

then i have this part in my code to define the combobox and its
content. the combobox content is shown as desired.

#Creates the dropdown list
self.combo1 = wx.ComboBox(self.panel, wx.ID_ANY,
choices=lottodates, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.onSelect)
self.sizer.Add(self.combo1, (5, 0), (1, 9), wx.EXPAND |
wx.ALL, border=5)

with this little function here im getting the value of self.combo1 and
create a new var with some numbers from another class. those numbers
are returned properly, as ive checked with print.

def onSelect(self, event):
lottodate = self.combo1.GetValue()
lottonumbers = lotto.getNumbers(lottodate, lottolist)
for number in lottonumbers:
self.setColors(number)

lastly i call following function in the for statement above to set the
background color of the panels. this function is supposed to set
firstly the panelname according to the number its called with, and
then changing the background color of the panel with the same number.

def setColors(self, number):
panelname = 'panel{0}'.format(number)
self.panelname.SetBackgoundColour('GREEN')

problem is that i get following error message when selecting a date
from the combobox:

Traceback (most recent call last):
File "C:\Documents and Settings\Sheepherd\Desktop\Lotto.pyw", line
62, in onSelect
self.setColors(number)
File "C:\Documents and Settings\Sheepherd\Desktop\Lotto.pyw", line
66, in setColors
self.panelname.SetBackgoundColour('GREEN')
AttributeError: 'Panel' object has no attribute 'SetBackgoundColour'

the ppl @ #wxpython had no idea why this didnt work so im asking you
guys here if you know why this wouldnt work.
you can get the whole code here: http://paste.pocoo.org/show/135809/ .
im using python 2.6.2 with wxpython wxPython 2.8.10.1 and Windows XP
SP3

Vlastimil Brom

unread,
Aug 23, 2009, 3:51:12 PM8/23/09
to wxpytho...@googlegroups.com
2009/8/23 Sheepherd <sheep...@gmail.com>:

>
> Well this is a little bit complex.
> ...

> Traceback (most recent call last):
>  File "C:\Documents and Settings\Sheepherd\Desktop\Lotto.pyw", line
> 62, in onSelect
>    self.setColors(number)
>  File "C:\Documents and Settings\Sheepherd\Desktop\Lotto.pyw", line
> 66, in setColors
>    self.panelname.SetBackgoundColour('GREEN')
> AttributeError: 'Panel' object has no attribute 'SetBackgoundColour'
>
> the ppl @ #wxpython had no idea why this didnt work so im asking you
> guys here if you know why this wouldnt work.
> you can get the whole code here: http://paste.pocoo.org/show/135809/ .
> im using python 2.6.2 with wxpython wxPython 2.8.10.1 and Windows XP
> SP3
>
>

Try
self.panelname.SetBackgroundColour("GREEN")
instead of
self.panelname.SetBackgoundColour('GREEN')

:-)

Vlasta

Sheepherd

unread,
Aug 23, 2009, 7:07:30 PM8/23/09
to wxPython-users
oh well... that happens when you concentrate too much on one piece of
code :/ sry 'bout that and thx :)

anyways. now it doesnt throw the error anymore but it just colors the
LAST panel of the frame. and this only after i move the frame out of
the screen or minimize it. an easy solution for this one too? :)
and again: when i use print number just before the actual coloring, it
returns the correct values

On Aug 23, 9:51 pm, Vlastimil Brom <vlastimil.b...@gmail.com> wrote:
> 2009/8/23 Sheepherd <sheepher...@gmail.com>:

C M

unread,
Aug 23, 2009, 8:19:27 PM8/23/09
to wxpytho...@googlegroups.com
On Sun, Aug 23, 2009 at 7:07 PM, Sheepherd <sheep...@gmail.com> wrote:

oh well... that happens when you concentrate too much on one piece of
code :/ sry 'bout that and thx :)

anyways. now it doesnt throw the error anymore but it just colors the
LAST panel of the frame.

I think because in this code:


   def setColors(self, number):
           panelname = 'panel{0}'.format(number)
           self.panelname.SetBackgoundColour('GREEN')

You are calling SetBackgroundColour() on the self.panelname, but
self.panelname was last updated to equal the last panel added.  Your
line above it does nothing to change self.panelname, just changes
panelname.  That is, panelname defines a name within the scope of
this setColors() function, whereas self.panelname refers to a name
within the scope of the whole class. 

Maybe what is better is to collect all your panels in a dict when you
make them, like {1:panel1, 2:panel2}, etc,, and then just do something
like:

def SetColors(self,number):
    self.paneldict[number].SetBackgroundColour('Green')
    self.paneldict[number].Update()

and this only after i move the frame out of
the screen or minimize it.

That is because after you do SetBackgroundColour() you have to
call Update() on that same panel, as shown above. 

Che
 

Vlastimil Brom

unread,
Aug 23, 2009, 8:45:15 PM8/23/09
to wxpytho...@googlegroups.com
2009/8/24 Sheepherd <sheep...@gmail.com>:

>
> oh well... that happens when you concentrate too much on one piece of
> code :/ sry 'bout that and thx :)
>
> anyways. now it doesnt throw the error anymore but it just colors the
> LAST panel of the frame. and this only after i move the frame out of
> the screen or minimize it. an easy solution for this one too? :)
> and again: when i use print number just before the actual coloring, it
> returns the correct values
>

You may try
self.panelname.SetBackgroundColour('GREEN')
self.panelname.Refresh()

if the background colour isn't updated instantly.

But without the external file lotto.txt we probably cannot reasonably
run your script, to see.

hth
Vlasta

C M

unread,
Aug 23, 2009, 11:02:05 PM8/23/09
to wxpytho...@googlegroups.com
On Sun, Aug 23, 2009 at 8:45 PM, Vlastimil Brom <vlastim...@gmail.com> wrote:

2009/8/24 Sheepherd <sheep...@gmail.com>:
>
> oh well... that happens when you concentrate too much on one piece of
> code :/ sry 'bout that and thx :)
>
> anyways. now it doesnt throw the error anymore but it just colors the
> LAST panel of the frame. and this only after i move the frame out of
> the screen or minimize it. an easy solution for this one too? :)
> and again: when i use print number just before the actual coloring, it
> returns the correct values
>

You may try
           self.panelname.SetBackgroundColour('GREEN')
           self.panelname.Refresh()

Yes, sorry it is Refresh(), not Update() as I'd said.

Sheepherd

unread,
Aug 25, 2009, 11:57:16 AM8/25/09
to wxPython-users
here comes the reworked version of my app.
changed the Lotto class slightly and managed to get the desired boxes
coloured
http://paste.pocoo.org/show/136176/
also here the lotto.txt for those who want it.
http://paste.pocoo.org/show/136177/

now i still got 2 issues to be solved. firstly the panels dont
get .refresh()ed properly, so i still have to minimize the window to
see the colors.
2nd is that i have no idea how to reset the color of the panel
(probably with an empty .SetBackgroundColor() ? )

thx for your help thus far

- Sheepherd

On Aug 24, 2:45 am, Vlastimil Brom <vlastimil.b...@gmail.com> wrote:
> 2009/8/24 Sheepherd <sheepher...@gmail.com>:

C M

unread,
Aug 25, 2009, 1:00:14 PM8/25/09
to wxpytho...@googlegroups.com
On Tue, Aug 25, 2009 at 11:57 AM, Sheepherd <sheep...@gmail.com> wrote:
>
> here comes the reworked version of my app.
> changed the Lotto class slightly and managed to get the desired boxes
> coloured
> http://paste.pocoo.org/show/136176/
> also here the lotto.txt for those who want it.
> http://paste.pocoo.org/show/136177/
>
> now i still got 2 issues to be solved. firstly the panels dont
> get .refresh()ed properly, so i still have to minimize the window to
> see the colors.

Here's the problem:  in both this code and the previous code, you
are treating two things as if they are the same, when they are not.
Note this function in your latest code:

def setColors(self, number):
panelname = self.paneldict[number].SetBackgroundColour('GREEN')
self.panelname.Refresh()

So you define something here, and it is named "panelname". You say
that this thing called panelname should be made green. Fine. But now
you know you have to .Refresh() whatever panel's color has been changed.
So one would expect to see this:

panelname.Refresh()

But what is seen is

self.panelname.Refresh()

The point is that panelname is different object than self.panelname. Self
panelname is an attribute of the whole instance of your class. panelname
is only a local name within this setColors() function. So, if you are going
to use this variable in other parts of this class, just do this:

def setColors(self, number):
self.panelname = self.paneldict[number].SetBackgroundColour('GREEN')
self.panelname.Refresh()

> 2nd is that i have no idea how to reset the color of the panel
> (probably with an empty .SetBackgroundColor() ? )

Not sure how to set that. You want it to be the "system" color, right?

Che

Mike Driscoll

unread,
Aug 25, 2009, 1:41:20 PM8/25/09
to wxPython-users
Hi Sheep!

<snip>

>
> The point is that panelname is different object than self.panelname.  Self
> panelname is an attribute of the whole instance of your class.  panelname
> is only a local name within this setColors() function.  So, if you are going
> to use this variable in other parts of this class, just do this:
>
>     def setColors(self, number):
>         self.panelname = self.paneldict[number].SetBackgroundColour('GREEN')
>         self.panelname.Refresh()
>
> > 2nd is that i have no idea how to reset the color of the panel
> > (probably with an empty .SetBackgroundColor() ? )
>
> Not sure how to set that.  You want it to be the "system" color, right?
>
> Che

I tried to find the docs on this earlier today and didn't have much
luck. I know Robin has told folks how to do this on several
occasions...fortunately, the term "system" was the one I was looking
for.

The docs here give a clue: http://www.wxpython.org/docs/api/wx.Colour-class.html

It looks like you want wx.SystemSettings.GetColour

Or something like this:

panel.SetBackgroundColour(wx.SystemSettings.GetColour
(wx.SYS_COLOUR_BACKGROUND))

- Mike

Sheepherd

unread,
Aug 25, 2009, 2:00:03 PM8/25/09
to wxPython-users
ah now i get it thx... i probably understand the whole oop concept a
lil bit better now

and yea it should be the system color althought i could change the
whole background anyways later

I figured it could kinda look like this:
added the for statement to call every single panel and set the color
for it which would be None as i found out with google. doesnt work
though :/

def onSelect(self, event):
for number in range(45):
self.setStandartColors(number)
lottodate = self.combo1.GetValue()
lottonumbers = lotto.getNumbers(lottodate, lottodict)
for number in lottonumbers:
self.setColors(number)

def setStandartColors(self, number):
number = number + 1
panelname = self.paneldict['{0:02d}'.format(number)]
panelname.SetBackgroundColour(None)


On Aug 25, 7:00 pm, C M <cmpyt...@gmail.com> wrote:

C M

unread,
Aug 25, 2009, 2:34:13 PM8/25/09
to wxpytho...@googlegroups.com
>
> ah now i get it thx... i probably understand the whole oop concept a
> lil bit better now

[This is not wxPython but Python stuff, but FWIW]

The way I wrote it above could have been clearer because I wrote what
should have been self.panelname as Self panelname. Maybe a simple
way to think about these things is: if you want a variable (in Python,
called a "name") to be accessible from anywhere in your class, put
a self. in front of it. If you want to just use it within a function and have
it only be defined within that function (within that "scope"), don't put a
self. in front of it. (the choice of the word "self" is just the convention,
it could be anything, but just use "self"). It is considered good form to
only make something self.name instead of just name if you *have* to
access it outside the function it is defined in, because otherwise you
are just cluttering up the class's namespace for no reason.

Che

Robin Dunn

unread,
Aug 25, 2009, 2:37:58 PM8/25/09
to wxpytho...@googlegroups.com
Mike Driscoll wrote:

>>
>>> 2nd is that i have no idea how to reset the color of the panel
>>> (probably with an empty .SetBackgroundColor() ? )
>> Not sure how to set that. You want it to be the "system" color, right?
>>
>> Che
>
> I tried to find the docs on this earlier today and didn't have much
> luck. I know Robin has told folks how to do this on several
> occasions...fortunately, the term "system" was the one I was looking
> for.
>
> The docs here give a clue: http://www.wxpython.org/docs/api/wx.Colour-class.html
>
> It looks like you want wx.SystemSettings.GetColour
>
> Or something like this:
>
> panel.SetBackgroundColour(wx.SystemSettings.GetColour
> (wx.SYS_COLOUR_BACKGROUND))

There's a better way, just use wx.NullColour. That will tell wx that
the widget has no specific color set and so it will use whatever the
platform wants to use, which may be controlled by the active theme and
may not be a solid color at all. This is a little different from using
the system settings color as then wx will act as if a custom color has
been set and it doesn't care if it happens to be the same as the system
color.


--
Robin Dunn
Software Craftsman
http://wxPython.org

Reply all
Reply to author
Forward
0 new messages