Search code examples
pythontkinterttk

ttk Style won't apply to frame in class


just started working with tkinter and i wanted to change the style of the frame but it won't. Can't figure it out so i'm asking you guys.

from tkinter import *
from tkinter import ttk
from tkinter import font
import currencyapi


class Currency():

    def __init__(self, parent):

        # App settings
        parent.title("CoinyAPP")
        icon = PhotoImage(file="icon.png")
        parent.iconphoto(False, icon)
        parent.eval("tk::PlaceWindow . center")

        # Font settings
        highlightFont = font.Font(
            family='Helvetica', name='appHighlightFont', size=12, weight='bold')

        # Widgets
        self.frame1 = ttk.Frame(
            parent, style="Frame1.TFrame").grid(row=0, column=0)

        ttk.Label(self.frame1, text="Pick a base currency.", font=highlightFont).grid(
            row=0, column=0, padx=48, pady=20)

        ttk.Label(self.frame1, text="Pick currency to convert into.", font=highlightFont).grid(
            row=0, column=2, padx=18, pady=20)

        self.amount = StringVar()
        currencyAmount = ttk.Entry(self.frame1, textvariable=self.amount)
        currencyAmount.grid(row=1, column=1, padx=40)

        self.baseCurrency = StringVar()
        base = ttk.Combobox(self.frame1, textvariable=self.baseCurrency, justify='center',
                            values=list(currencyapi.currencyData['rates'].keys()))
        base.grid(row=1, column=0)
        base.current(46)

        self.convertInto = StringVar()
        convert = ttk.Combobox(self.frame1, textvariable=self.convertInto, justify='center',
                               values=list(currencyapi.currencyData['rates'].keys()))
        convert.grid(row=1, column=2)
        convert.current(0)

        ttk.Button(self.frame1, command=self.currency_convertion,
                   text='Convert!').grid(row=2, column=1, padx=40, pady=15)

        self.result = StringVar()
        ttk.Label(self.frame1, font=highlightFont,
                  textvariable=self.result).grid(row=3, column=1, pady=5)

    def currency_convertion(self, *args):
        self.conv = currencyapi.currencyData['rates'].get(
            self.convertInto.get())
        self.amountNumber = self.amount.get()
        self.base = currencyapi.currencyData['rates'].get(
            self.baseCurrency.get())
        Ans = (float(self.conv) * float(self.amountNumber)) / float(self.base)
        self.result.set("%.2f" % Ans)


root = Tk()
s = ttk.Style()
s.configure("Frame1.TFrame", background='yellow',
            foreground='blue')
Currency(root)
root.mainloop()

It's probably not very well written, sorry for that! Started programming few weeks ago.

Tried to put it into Currency class and outside, both didn't work.


Solution

  • It's possible that the problem is here:

    self.frame1 = ttk.Frame(parent, style="Frame1.TFrame").grid(row=0, column=0)
    

    The geometry manager methods (pack, grid, place) return None, so self.frame1 is evaluating to None

    To fix this, declare your frame and then put it on the grid separately:

    self.frame1 = ttk.Frame(parent, style="Frame1.TFrame")
    self.frame1.grid(row=0, column=0)
    

    That said, I put together a quick boilerplate app to test this and it seemed to work without issues...

    """Tkinter Boilerplate App Example"""
    import tkinter as tk
    from tkinter import ttk
    
    
    class App(tk.Tk):
        def __init__(self):
            super.__init__()
            self.geometry('200x200')
            self.title('Stylish')
            self.frame = ttk.Frame(self, style='Frame1.TFrame')
            self.frame.pack(expand=True, fill=tk.BOTH)  # fill available space
            self.style = ttk.Style()
            # note: 'foreground' doesn't appear to have any effect on a Frame
            self.style.configure('Frame1.TFrame', background='pink', foreground='red')
    
    
    if __name__ == '__main__':
        app = App()
        app.mainloop()