Mac系统如何修改Python Tkinter ttk.OptionMenu控件周围背景色
问题描述
- 开发基于tkinter的星期选择脚本,预期效果为用户选中对应星期选项后,窗口直接展示用户选中的星期值
- Mac系统环境下,将窗口整体背景设置为黑色时,
ttk.OptionMenu星期选择控件周围的背景区域始终无法同步变为黑色,存在显示异常 - 问题复现代码:
from tkinter import * import tkinter.ttk as ttk root= Tk() root.geometry('200x300') root.configure(bg= 'black') def selected(event): Label(root, text= clicked.get(), bg= 'black').pack() clicked.set(options[0]) options= ['Pick A Day', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] clicked= StringVar() clicked.set(options[0]) drop= ttk.OptionMenu(root, clicked, *options, command= selected) drop.pack(pady= 20) root.mainloop()
问题原因
Mac端tkinter的ttk控件默认使用系统原生Aqua主题渲染,控件的外围留白、边框区域由系统原生UI框架负责绘制,不响应tkinter常规的bg背景色配置参数,因此直接修改窗口背景后,这部分区域仍保留系统默认的白色。
可行解决方法
两种方案选一种就能解决问题:
方案1:换用tkinter原生
OptionMenu(非ttk版本)
原生tk控件不依赖系统原生渲染逻辑,支持直接通过参数修改控件背景、文字颜色,完美适配黑底需求,核心修改代码如下:# 替换原有的ttk.OptionMenu调用,使用tkinter内置的OptionMenu drop= OptionMenu(root, clicked, *options, command= selected) # 配置控件本身的黑底白字样式,去掉焦点高亮边框 drop.config(bg='black', fg='white', highlightthickness=0) # 同步配置下拉弹出菜单的黑底白字样式 drop['menu'].config(bg='black', fg='white') drop.pack(pady= 20)注意同步把选中后展示的
Label加上fg='white'参数,避免黑底黑字看不到内容。方案2:保留ttk控件,替换ttk渲染主题
如果需要保留ttk控件的其他特性,可以把ttk默认的Aqua主题换成支持自定义样式的跨平台主题(比如clam),再通过ttk样式配置统一修改OptionMenu的颜色,完整可运行代码如下:from tkinter import * import tkinter.ttk as ttk root= Tk() root.geometry('200x300') root.configure(bg= 'black') # 替换ttk默认主题,初始化样式配置 style = ttk.Style(root) style.theme_use('clam') # 配置OptionMenu控件的黑底白字样式 style.configure('TMenubutton', background='black', foreground='white', borderwidth=0) # 配置下拉弹出列表的黑底白字样式 root.option_add('*Menu.background', 'black') root.option_add('*Menu.foreground', 'white') def selected(event): Label(root, text= clicked.get(), bg= 'black', fg='white').pack() clicked.set(options[0]) options= ['Pick A Day', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] clicked= StringVar() clicked.set(options[0]) drop= ttk.OptionMenu(root, clicked, *options, command= selected) drop.pack(pady= 20) root.mainloop()
内容的提问来源于stack exchange,提问作者Ori Daniel
相关产品推荐
相关产品推荐

