如何更改 Mac OS X 上 Tkinter 按钮的前景色或背景颜色?
- 2025-02-13 08:36:00
- admin 原创
- 39
问题描述:
我一直在研究《Python 编程》中的 Tkinter 章节,遇到了一个问题,按钮的前景色和背景色不会改变。我正在使用 Python 2.6.1 的 Mac OS X 10.6 系统上工作。标签的颜色会改变,但按钮的颜色不会改变。例如:
from Tkinter import *
Label(None, text='label', fg='green', bg='black').pack()
Button(None, text='button', fg='green', bg='black').pack()
mainloop()
在我的 Mac 系统上,标签的颜色会改变,但按钮的颜色不会改变。在装有 Python 2.6.1 的 Windows 系统上,标签和按钮的颜色都会改变。
有人知道发生了什么问题吗?
我检查了 Interface Builder,发现该工具中似乎没有更改按钮前景色或背景色的选项。可以编辑标签的前景色和背景色。
Mac OS X 渲染系统(Quartz?)可能不支持(轻松)更改按钮的 fg 和 bg。
解决方案 1:
有一个解决方案可以更改Mac 上按钮的背景。
使用:
highlightbackground=color
例如:
submit = Button(root, text="Generate", highlightbackground='#3E4149')
结果是以下,一个与背景相适应的漂亮按钮:
解决方案 2:
我认为答案是 Mac 上的按钮根本不支持更改背景和前景色。如您所见,这并非 Tk 独有的。
解决方案 3:
您可以使用PyPI 的tkmacosx库来完成此操作。
安装:
对于 Python 2,使用
pip install tkmacosx
。对于 Python 3,使用
pip3 install tkmacosx
。
使用方式如下tkmacosx
:
from tkinter import *
from tkmacosx import Button
root = Tk()
B1 = Button(root, text='Mac OSX', bg='black',fg='green', borderless=1)
B1.pack()
root.mainloop()
它在 Mac OS X 上运行良好。
解决方案 4:
对于像我一样遇到这个问题的其他人,解决方案是使用ttk模块,该模块在 OS X 10.7 上默认可用。不幸的是,设置背景颜色仍然不能立即使用,但文本颜色可以。
它需要对代码进行一点改动:
原来的:
from Tkinter import *
Label(None, text='label', fg='green', bg='black').pack()
Button(None, text='button', fg='green', bg='black').pack()
mainloop()
使用 ttk:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# background="..." doesn't work...
ttk.Style().configure('green/black.TLabel', foreground='green', background='black')
ttk.Style().configure('green/black.TButton', foreground='green', background='black')
label = ttk.Label(root, text='I am a ttk.Label with text!', style='green/black.TLabel')
label.pack()
button = ttk.Button(root, text='Click Me!', style='green/black.TButton')
button.pack()
root.mainloop()
解决方案 5:
很烦人的是,多年以后这个问题仍然存在。
无论如何,正如其他人提到的那样,highlightbackground(边框颜色)可以代替 Mac 上的背景。如果将边框的大小增加到很大(按钮的大小或更大),您将获得漂亮的纯色背景。这将使您的按钮看起来像一个标签。
如果您使用 place,这种方法可行,但如果您使用 grid 之类的东西,这种方法就不行。不幸的是,使用 grid 时,增加边框尺寸会自动增加按钮尺寸。
但是,如果您必须使用网格,您可以随时对其进行破解....创建无色网格按钮。接下来使用 place 将背景颜色按钮置于其上方。这将是带有“命令”的按钮或您绑定事件的按钮。
如果您希望代码独立于操作系统,您可以添加“if OS ==“Mac””语句,甚至可以添加自定义函数,如果按钮在 Mac 上则修改按钮,但在 Windows 或 Linux 上则保持不变。以下是前者:
from tkinter import *
import platform
if platform.system() == "Darwin": ### if its a Mac
B = Button(text="Refersh All Windows", highlightbackground="Yellow", fg="Black", highlightthickness=30)
else: ### if its Windows or Linux
B = Button(text="Refresh All Windows", bg="Yellow", fg="Black")
B.place(x=5, y=10, width=140, height=30)
mainloop()
解决方案 6:
我一直在寻找为什么这个方法不起作用。我发现一个快速修复它的方法是使用标签,然后将点击与标签绑定。然后让标签短暂改变颜色以模仿点击。这是一个例子。
def buttonPress(*args):
searchB.config(state = "active")
searchB.update()
time.sleep(0.2)
searchB.config(state = "normal")
## Whatever command you want
searchB = Label(main, text = "Search", bg = "#fecc14", fg = "Black", activebackground = "Red", highlightbackground="Black")
searchB.bind("<Button-1>", startSearch)
searchB.pack()
解决方案 7:
这对我有用:
self.gnuplot_bt = Button(
self.run_but_container, text="Plot with Gnuplot", font="Helvetica", command=self.gnuplot,
highlightbackground ="#8EF0F7", pady=2, relief=FLAT
)
解决方案 8:
确认以下代码可以改变Mac OS X上tkinter按钮的背景。
self.btn_open = tk.Button(self.toolbar,
text = "Open",
command=self.open,
highlightbackground = "gray")
但它不能改变 ttk.Button 的背景。
解决方案 9:
不确定是否还有人在看这个帖子,但我通过创建自己的 Button 类为这个问题创建了一个简单的解决方案。它可以在GitHub上找到。
import tkinter as tk
class Button():
button_frame = None
root = None
width=100
height=20
text=""
bg="white"
fg="black"
font="f 12"
bordercolor = "black"
bordersize = 3
label = None
command = None
def __init__(self,root,width=100,height=20,text="",bg="white",fg="black",font="f 12",command=None,bordercolor="black",bordersize=0):
self.root = root
self.width=width
self.height=height
self.text=text
self.bg=bg
self.fg=fg
self.font=font
self.command = command
self.bordercolor = bordercolor
self.bordersize = bordersize
self.button_frame = tk.Frame(root,width=width,height=height,bg=bg)
self.label = tk.Label(self.button_frame,text=self.text,bg=self.bg,width=self.width,height=self.height,fg=self.fg,font=self.font,highlightbackground=self.bordercolor,highlightthickness=self.bordersize)
self.label.place(anchor="center",relx=0.5,rely=0.5,relheight=1,relwidth=1)
self.label.bind("<Button-1>",self.call_command)
def call_command(self,event):
if (self.command != None):
self.command()
def place(self,anchor="nw",relx=0,rely=0):
self.button_frame.place(anchor=anchor,relx=relx,rely=rely)
def configure(self,width=width,height=height,text=text,bg=bg,fg=fg,font=font,command=command,bordercolor=bordercolor,bordersize=bordersize):
self.button_frame.configure(width=width,height=height,bg=bg)
self.label.configure(text=text,bg=bg,width=width,height=height,fg=fg,font=font,highlightbackground=bordercolor,highlightthickness=bordersize)
self.command =
解决方案 10:
对我来说,按钮和标签似乎非常相似,因此我发现标签和按钮的工作方式不同很奇怪......即使过了这么多年。
您可以随时创建自己的按钮类,该类包裹着一个带边框的标签(默认宽度为 2),并绑定按钮释放的调用。您可能会错过按钮按下和释放的一些“动画”,但您可以获得所需的背景和前景色。
我编写了一个名为Tagged Text Widgets(PyPI.org 上的“ttwidgets”)的项目,它本质上就是这么做的。我编写该项目是为了允许多字体、多颜色的按钮和标签。本质上,该项目创建了一个复合按钮或标签,由多个底层标签小部件(每个都有自己的颜色/字体)组成,但充当单个对象。这些不同的颜色和字体是通过传入类似 HTML 的标记文本代替常规文本来创建的。而且由于底层标签而不是按钮,它可以解决 macOS 上的问题。
我刚刚在 macOS Sierra 上对其进行了测试,它解决了按钮 bg/fg 颜色问题。
您可以按如下方式使用它:
from ttwidgets import TTButton
TTButton 支持 Tkinter Button 的完整界面,但还具有许多增强功能。但对于试图解决 macOS 颜色问题的人来说,只需使用 TTButton 代替 Tkinter Button 就足够了。
解决方案 11:
a 我遇到了类似的问题。我正在构建一个应用程序,其中 GUI 与 MacOS 和 Windows OS 兼容。
问题:我想从图像创建一个按钮。但是,它必须在 MacOS 和 Windows 上都能工作(或者至少分别为它们找到解决方案)。Tkinter.Button 在 MacOS 上无法工作,而 Tkmacosx.Button 的行为不理想。
我会发布一些代码,但答案很简单,ttk.Button()
两者都适用。
但是,使用 ttk 按钮时,单击按钮时没有移动动画。当所有边框都消失并且所有不同的背景颜色都设置为相同颜色时,按钮不会移动,从而向用户确认按钮已被单击。
为了解决这个问题,我们将点击和点击释放都绑定到它们自己的方法上。这两种方法都只是.place
按钮,点击 x 和 y +1 像素,取消点击将按钮送回其起始位置。
class Root(bootstrap.Window):
"""
Root UI comprised of import button and 'up-to-date' tracking system indicator
"""
def __init__(self):
super().__init__()
self.settings = UIOptions().settings
# Window Configuration
self.title("Automated Expenses Manager")
self.option_add("*tearOff", False)
self.geometry("1000x700")
self.resizable(False, False)
self.config(background='dark grey')
# Arrow Image Button
style = bootstrap.Style()
style.configure(style='Arrow.TButton', background='dark grey',
highlightcolor='dark grey', borderwidth=0,
focuscolor='dark grey')
style.map('Arrow.TButton',
background=[('active', 'dark grey')],)
arrow_image = ImageTk.PhotoImage(Image.open(ARROW_IMAGE).resize((235, 150), Image.Resampling.LANCZOS))
self.arrow = bootstrap.Button(self,
style='Arrow.TButton',
image=arrow_image)
self.arrow.bind("<Button-1>", self.click)
self.arrow.bind("<ButtonRelease-1>", self.unclick)
self.arrow.place(x=390, y=80, anchor='nw')
self.mainloop()
def click(self, event):
self.arrow.place(x=391, y=81, anchor='nw')
def unclick(self, event):
self.arrow.place(x=390, y=80, anchor='nw')
在这个类中,你会看到我做了一个样式映射style.map()
。第一个位置参数是要修改的样式名称,在我的代码中,我命名了一个要修改的属性,并向其发送了一个元组列表。每个元组都指示一个特定事件以及当事件发生时将设置的命名属性的值。
我在将鼠标悬停在按钮上时遇到了问题。它会改变按钮的背景颜色。解决方案是将“活动” - 当鼠标悬停在小部件上时,映射到与根窗口背景颜色相同的颜色('active', 'dark grey')
。这会阻止小部件在悬停时改变颜色,因为它只是更改为背景已有的相同颜色。
该代码在 MacOS 和 Windows 上均可完美运行。
希望有帮助!
解决方案 12:
平台:Mac OS X
操作系统:14.1.1(Mac OS Sonoma)
安装或更新 tcl-tk 实用程序后,我们需要安装 python。在我的例子中,包管理器是 brew
brew uninstall tcl-tk --devel
brew install tcl-tk
在我的例子中,tcl-tk 安装到目录中
/opt/homebrew/Cellar/tcl-tk/8.6.13_5
如果你使用 ZSH
echo "# For tkinter
export PATH=\"/opt/homebrew/Cellar/tcl-tk/8.6.13_5/bin:$PATH\"" >> ~/.zshrc
如果你使用 BASH
echo "# For tkinter
export PATH=\"/opt/homebrew/Cellar/tcl-tk/8.6.13_5/bin:$PATH\"" >> ~/.bashrc
我正在使用 pyenv 安装 python 版本 3.10.6
pyenv install 3.10.6
pyenv virtualenv 3.10.6 your virtual_env_name
Tkinter 示例代码
from tkinter import Tk, Frame, Button, BOTTOM, LEFT, RIGHT, TOP
root = Tk()
frame1 = Frame(root)
frame1.pack()
frame2 = Frame(root)
frame2.pack(side=BOTTOM)
button1 = Button(frame1, text="Red Button", command=lambda: "Red Button", fg='red')
button1.pack(side=LEFT)
button2 = Button(frame1, text="Blue Button", command=lambda: "Blue Button", fg='blue')
button2.pack(side=RIGHT)
button3 = Button(frame1, text="Cyan Button", command=lambda: "Cyan Button", fg='cyan')
button3.pack(side=TOP)
button4 = Button(frame1, text="White Button", command=lambda: "White Button", fg='white')
button4.pack(side=BOTTOM)
root.mainloop()
输出: