Sabawoon
Sabawoon

Reputation: 37

change Tkinter frame color with for loop from list of colors

I have the following code snippet. What i need to code that when i click the button i need the frame color to change one by one from the list of colors defined.

 from tkinter import *
 from tkinter import ttk

def ChangeColor():
colors = ['red','green', 'orange','blue']
for color in colors:
    #color = entry.get()
    frame.config(bg = color)

root = Tk()
root.title("Title")

frame = Frame (root, width = 260, height = 200)
frame.pack()

btn = ttk.Button(frame, text = 'Change color', command = ChangeColor)
btn.place (x = 80, y = 100)

entry = ttk.Entry (frame, width = 20)
entry.place(x = 80, y = 70)

root.mainloop()

Upvotes: 2

Views: 1661

Answers (3)

ragardner
ragardner

Reputation: 1975

I would change your app to a class so you can store variables and access them easily, also I bound the enter key to the entry widget so that works too. This way when you create an instance of class app it is an instance of a Tk() root, but you don't have to call it root

import tkinter as tk
from tkinter import ttk

class app(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Title")
        self.frame = tk.Frame(self, width = 260, height = 200)
        self.frame.pack()

        self.btn = ttk.Button(self.frame, text = 'Change color', command = self.ChangeColor)
        self.btn.place (x = 80, y = 100)

        self.entry = ttk.Entry (self.frame, width = 20)
        self.entry.place(x = 80, y = 70)
        self.entry.bind("<Return>",self.ChangeColorEntry)

        self.colors = ['red','green','orange','blue']
        self.current_color = -1
        self.standard_bg = self.frame['background']

    def ChangeColor(self,event=None):
        if self.current_color == len(self.colors) - 1:
            self.frame.config(bg = self.standard_bg)
            self.current_color = -1
            return
        else:
            self.current_color += 1
        color = self.colors[self.current_color]
        self.frame.config(bg = color)

    def ChangeColorEntry(self,event=None):
        entered = self.entry.get().lower().strip()
        if entered == "none":
            self.frame.config(bg = self.standard_bg)
        else:
            try:
                self.current_color = self.colors.index(entered)
                self.frame.config(bg = entered)
            except:
                pass

Upvotes: 2

AlanK
AlanK

Reputation: 9843

@PM 2Rings answer is cleaner but since I was working on this I thought I'd still post it incase you wanted to implement it manually

from tkinter import *
from tkinter import ttk

colors = ['red', 'green', 'orange', 'blue']
colors_it = iter(colors)

def get_next_color():
    try:
        global colors_it
        return next(colors_it)
    except StopIteration:
        colors_it = iter(colors)
        return next(colors_it)

def ChangeColor():
    frame.config(bg=get_next_color())

root = Tk()
root.title("Title")

frame = Frame (root, width = 260, height = 200)
frame.pack()

btn = ttk.Button(frame, text = 'Change color', command = ChangeColor)
btn.place (x = 80, y = 100)

entry = ttk.Entry (frame, width = 20)
entry.place(x = 80, y = 70)

root.mainloop()

Upvotes: 1

PM 2Ring
PM 2Ring

Reputation: 55489

You can use the cycle iterator from itertools for this.

from tkinter import *
from tkinter import ttk
from itertools import cycle

root = Tk()
root.title("Title")

frame = Frame (root, width = 260, height = 200)
frame.pack()

colors = ['red','green', 'orange','blue']
color_gen = cycle(colors)

def ChangeColor():
    frame.config(bg = next(color_gen))

btn = ttk.Button(frame, text = 'Change color', command = ChangeColor)
btn.place (x = 80, y = 100)

entry = ttk.Entry (frame, width = 20)
entry.place(x = 80, y = 70)

root.mainloop()

One thing I need to mention: please avoid doing "star" imports. When you do

from tkinter import *

it puts 135 Tkinter names into your namespace; in Python 2 you get 175 names. This creates needless clutter in the namespace and it can cause name collisions: if you accidentally name one of your variables with one of the imported names that can lead to mysterious bugs. It's even worse when you do star imports with multiple modules since they can stomp over each others' names. Also, star imports make the code harder to read since you have to remember which names are defined locally and which are imported.

Upvotes: 5

Related Questions