ttk Style无法应用于类中Frame的问题求助
问题:tkinter中ttk Frame样式无法生效
我刚开始接触tkinter,想要为类中的Frame设置ttk样式,但样式始终无法生效。我尝试将样式配置代码放在Currency类内部和外部,均未解决问题。以下是我的代码:
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()
注:我刚编程几周,代码可能不够规范,还请见谅。
解决方案
核心问题出在Frame创建时的链式调用:
self.frame1 = ttk.Frame(parent, style="Frame1.TFrame").grid(row=0, column=0)
grid()方法返回的是None,导致self.frame1实际为None——后续所有组件都没有挂载到这个Frame上,而是直接绑定到了父窗口,Frame本身根本没显示,样式自然无法生效。
修改步骤:
- 拆分Frame的创建与布局,先实例化Frame对象,再单独调用
grid():
self.frame1 = ttk.Frame(parent, style="Frame1.TFrame") self.frame1.grid(row=0, column=0)
- 为了让Frame的背景色更明显,可添加
padx/pady给Frame设置内边距,避免被内部组件完全覆盖。 - 部分ttk主题中
background属性可能不生效,可同时设置fieldbackground确保兼容。
修改后的完整代码:
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 - 拆分Frame创建与布局 self.frame1 = ttk.Frame(parent, style="Frame1.TFrame") self.frame1.grid(row=0, column=0, padx=10, pady=10) 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', fieldbackground='yellow') Currency(root) root.mainloop()
额外提示:
- 永远不要把组件创建和布局的链式调用写在一起,分开写才能保留组件对象的引用,方便后续修改。
- ttk组件的样式属性和普通tk组件有差异,遇到样式不生效时,可以多尝试相关属性(比如
fieldbackground、bordercolor等)。
内容的提问来源于stack exchange,提问作者mleszcz
相关产品推荐
相关产品推荐

