?
Solved

python tkinter, changing label colors

Posted on 2011-04-21
6
Medium Priority
?
4,379 Views
Last Modified: 2012-05-11
I am learning python tkinter and have written an app that responds to clicking on a button: for each button clicked, the label in the largest frame changes to reflect the color chosen. But only the words. I can't configure the background color of the label, I think because the app sees the label as none type object. What to do? The code is attached, with my comments to reflect the errors that I saw.
from Tkinter import *

class Application(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master=None)
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)
        self.grid(sticky=N+S+E+W)
        self.event = "<Button-1>"
        event = self.event
        self.__BuildFrames(event)

    def __ButtonHandler(self, event, f, v, r, s, color, i):
        if i == 1:
            f.configure(bg = "red")
            r.set("You picked red")
        elif i == 2:
            f.configure(bg = "blue")
            # s (Label) is a nonType object...so s.config won't work
            color.set('blue') #nothing - and s.color.set is none-type object
            r.set("You picked blue")
        elif i == 3:
            f.configure(bg = "green")
            r.set("You picked green")
        elif i == 4:
            f.configure(bg = "black")
            r.set("You picked black")
        elif i == 5:
            f.configure(bg = "red")
            v.set("Random file")
            r.set("You wish to open a file")

    def __HandlerBlue(self, event):
        print("Frame 1 clicked at", event.x, event.y)

    def __HandlerWhite(self, event):
        print("Frame 2 clicked at", event.x, event.y)

    def __BuildFrames(self, event):

        for x in range(1, 3):
            self.rowconfigure(x, weight=1)

        d = Frame(self, bg="blue")
        Label(self, text="Frame 1", bg="blue").grid(row=1, column=1, sticky=E, pady=50)
        d.grid(row=1, column=1, columnspan=2, sticky=N+S+E+W)
        d.bind(event, self.__HandlerBlue)

        e = Frame(self, bg="white")
        Label(self, text="Frame 2", bg="white").grid(row=2, column=1, sticky=E, pady=50)
        e.grid(row=2, column=1, columnspan=2, sticky=N+S+E+W)
        e.bind(event, self.__HandlerWhite)

        f = Frame(self, bg="red")
        r = StringVar()
        Label(self, textvariable=r, bg="red").grid(row=1, column=4, sticky=S)
        r.set("Frame 3")
        f.grid(row=1, column=3, rowspan=2, columnspan=3, sticky=N+S+E+W)
        self.f = f

        g = Frame(self)
        v = StringVar()
        # color.set('red') unknown color name "PY_VAR2"
        color = "red"
        s = Label(self, text="Open File", bg=color, borderwidth=2).grid(row=2, column=4, sticky=S+E)
        entry_widget = Entry(self, text=v, width=10).grid(row=2, column=5, sticky=S+E)
        # s is a NoneType object
        g.grid(row=2, column=5)

        color = StringVar()
        self.color = color
        self.v = v
        self.r = r
        self.__CreateButtons(event, f, v, r, s, color)
        self.pack()

    def __CreateButtons(self, event, f, v, r, s, color):

        self.button_dict = { 'button1': 'Red', 'button2': 'Blue', 'button3': 'Green', 'button4': 'Black', 'button5': 'Open' }
        for i in range(1, 6):
            for y in self.button_dict.keys():
                label = self.button_dict[y]
                if i == int(y[-1]):
                    y = Button(self, text=label)
                    y.grid(row=3, column=i, ipadx=10, sticky=N+S+E+W)
                    def handler( event, i=i):
                        return self.__ButtonHandler(event, f, v, r, s, color, i)
                    y.bind(event, handler, self)

root = Tk()
app = Application(master=root)
app.pack()
app.mainloop()

Open in new window

0
Comment
Question by:sara_bellum
  • 3
  • 3
6 Comments
 
LVL 29

Accepted Solution

by:
pepr earned 2000 total points
ID: 35446652
See the line 66.  The s is of NoneType because it is not the Label object.  It is the result of the .grid() method applied to the Label object.  You have to split the one-liner.  Moreover, you want to capture the s of the "Frame 3" label, not the one of the "Open File" label.
0
 
LVL 29

Assisted Solution

by:pepr
pepr earned 2000 total points
ID: 35446667
Try the following code:

a.py
from Tkinter import *

class Application(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master=None)
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)
        self.grid(sticky=N+S+E+W)
        self.event = "<Button-1>"
        event = self.event
        self.__BuildFrames(event)

    def __ButtonHandler(self, event, f, v, r, s, color, i):
        if i == 1:
            color = "red"
            f.configure(bg=color)
            s.configure(bg=color)
            r.set("You picked " + color)
        elif i == 2:
            color = "blue"
            f.configure(bg=color)
            s.configure(bg=color)
            r.set("You picked " + color)
        elif i == 3:
            color = "green"
            f.configure(bg=color)
            s.configure(bg=color)
            r.set("You picked " + color)
        elif i == 4:
            color = "black"
            f.configure(bg=color)
            s.configure(bg='white')  # an exception to make it readable
            r.set("You picked " + color)
        elif i == 5:
            color = "red"
            f.configure(bg=color)
            s.configure(bg=color)
            v.set("Random file")
            r.set("You wish to open a file")

    def __HandlerBlue(self, event):
        print("Frame 1 clicked at", event.x, event.y)

    def __HandlerWhite(self, event):
        print("Frame 2 clicked at", event.x, event.y)

    def __BuildFrames(self, event):

        for x in range(1, 3):
            self.rowconfigure(x, weight=1)

        d = Frame(self, bg="blue")
        Label(self, text="Frame 1", bg="blue").grid(row=1, column=1, sticky=E, pady=50)
        d.grid(row=1, column=1, columnspan=2, sticky=N+S+E+W)
        d.bind(event, self.__HandlerBlue)

        e = Frame(self, bg="white")
        Label(self, text="Frame 2", bg="white").grid(row=2, column=1, sticky=E, pady=50)
        e.grid(row=2, column=1, columnspan=2, sticky=N+S+E+W)
        e.bind(event, self.__HandlerWhite)

        f = Frame(self, bg="red")
        r = StringVar()
        s = Label(self, textvariable=r, bg="red")
        s.grid(row=1, column=4, sticky=S)
        r.set("Frame 3")
        f.grid(row=1, column=3, rowspan=2, columnspan=3, sticky=N+S+E+W)
        self.f = f

        g = Frame(self)
        v = StringVar()
        # color.set('red') unknown color name "PY_VAR2"
        color = "red"
        Label(self, text="Open File", bg=color, borderwidth=2).grid(row=2, column=4, sticky=S+E)
        entry_widget = Entry(self, text=v, width=10).grid(row=2, column=5, sticky=S+E)
        g.grid(row=2, column=5)

        color = StringVar()
        self.color = color
        self.v = v
        self.r = r
        self.__CreateButtons(event, f, v, r, s, color)
        self.pack()

    def __CreateButtons(self, event, f, v, r, s, color):

        self.button_dict = { 'button1': 'Red', 
                             'button2': 'Blue', 
                             'button3': 'Green', 
                             'button4': 'Black', 
                             'button5': 'Open' }
        for i in range(1, 6):
            for y in self.button_dict.keys():
                label = self.button_dict[y]
                if i == int(y[-1]):
                    y = Button(self, text=label)
                    y.grid(row=3, column=i, ipadx=10, sticky=N+S+E+W)
                    def handler( event, i=i):
                        return self.__ButtonHandler(event, f, v, r, s, color, i)
                    y.bind(event, handler, self)

root = Tk()
app = Application(master=root)
app.pack()
app.mainloop()

Open in new window


Anyway, you may want to change the background of both the "Frame 3" and "Open File" labels.  It may be better to detect the colour of the frame and set the label background accordingly.  I am not good in tkinter, however.
0
 

Author Comment

by:sara_bellum
ID: 35451157
That was it (combining the grid method with the label object)! I should have caught that, especially since I had to break out the grid method from its object for some other problem I was having with this app. But I've worked with it for so long that I couldn't see it :(  

Thanks for your code nonetheless! I found out that I don't need the set() method except for the stringVar that I want inserted into the text entry widget. To change label text etc all I needed was this:
s.configure(text="You picked \n" + color, fg="white", bg=color)

I don't know if I'll use much tkinter, but it's been useful to help me visualize the relationships between objects and methods in a class :)
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Closing Comment

by:sara_bellum
ID: 35451163
It's awesome to get this kind of feedback!!
0
 
LVL 29

Expert Comment

by:pepr
ID: 35452220
Well, our future is awesome.  We only have to get rid of the mental and physical mess ;)

Concerning the "blindness", this is very normal.  We have the proverb "more heads know more" which is likely the equivalent of the English "Two heads are better then one."  In the case of the blindness, it really works even if the other head is passive (i.e. you have to explain your own code to someone else).  We have modified the proverb for such case (with my colleague) to "The more heads, the more cabbage." :)
0
 

Author Comment

by:sara_bellum
ID: 35462721
:)
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

"The time has come," the Walrus said, "To talk of many things: Of sets--and lists--and dictionaries-- Of variable kinks-- And why you see it changing not-- And why so strange are strings." This part describes how variables and references (see …
Sequence is something that used to store data in it in very simple words. Let us just create a list first. To create a list first of all we need to give a name to our list which I have taken as “COURSE” followed by equals sign and finally enclosed …
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …

615 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question