Как изменить цвет фона или текста кнопки Tkinter на Mac OS X?
Я работаю над главами Tkinter в книге "Programming Python" и столкнулся с проблемой, из-за которой цвета фона и текста кнопки не изменяются. Я использую систему Mac OS X 10.6 с Python 2.6.1. Цвета метки изменяются, но не цвета кнопки. Вот пример кода:
from Tkinter import *
Label(None, text='label', fg='green', bg='black').pack()
Button(None, text='button', fg='green', bg='black').pack()
mainloop()
На моей системе Mac цвета метки работают, но цвета кнопки остаются прежними. На системе Windows с Python 2.6.1 цвета как метки, так и кнопки изменяются корректно.
Кто-нибудь знает, в чем может быть проблема?
Я проверял Interface Builder и не нашел опции для изменения цвета фона или текста кнопки в этом инструменте. Есть возможность редактировать цвета метки.
Возможно, система рендеринга Mac OS X (Quartz?) просто не поддерживает (или не легко поддерживает) изменение цветов fg и bg для кнопки.
5 ответ(ов)
Я думаю, что причина в том, что кнопки на Mac просто не поддерживают изменение фона и цвета текста. Как вы уже заметили, это не уникально для Tk.
Если вы столкнулись с проблемой, при которой не работает ваша кнопка, одним из быстрых способов решения может быть использование метки (Label) и связывание события нажатия с этой меткой. Затем вы можете изменить цвет метки на короткое время, чтобы имитировать нажатие кнопки. Вот пример кода, который иллюстрирует этот подход:
def buttonPress(*args):
searchB.config(state="active")
searchB.update()
time.sleep(0.2)
searchB.config(state="normal")
# Здесь вы можете разместить любую нужную команду
searchB = Label(main, text="Search", bg="#fecc14", fg="Black", activebackground="Red", highlightbackground="Black")
searchB.bind("<Button-1>", startSearch)
searchB.pack()
В этом примере мы создаем метку с текстом "Search" и связываем событие нажатия кнопки мыши (Button-1) с функцией startSearch
. Вы можете перенастроить buttonPress
, чтобы добавить дополнительную логику, реагирующую на ваше конкретное событие.
Это сработало для меня:
self.gnuplot_bt = Button(
self.run_but_container, text="Построить график с Gnuplot", font="Helvetica", command=self.gnuplot,
highlightbackground="#8EF0F7", pady=2, relief=FLAT
)
Да, представленный вами код может изменить фон кнопки в Tkinter на Mac OS X. В конкретном примере используется параметр highlightbackground
, который изменяет цвет фона кнопки в состоянии, когда она не активна. Однако стоит обратить внимание на то, что использование стандартного tk.Button
позволяет легко изменять его фон.
Тем не менее, когда вы используете ttk.Button
, вы не сможете изменить цвет фона (или "bg") напрямую, так как ttk
реализует кнопки с использованием стилей, которые зависят от платформы. Вместо этого вам нужно использовать метод настройки стиля TTk, например через класс ttk.Style
. Вот пример, как можно изменить фон ttk.Button
:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# Создание стиля для ttk.Button
style = ttk.Style()
style.configure('TButton', background='gray')
# Создание кнопки с применённым стилем
self.btn_open = ttk.Button(root, text="Open", command=self.open, style='TButton')
self.btn_open.pack()
root.mainloop()
Таким образом, для изменения фона ttk.Button
нужно использовать стиль, в отличие от обычного tk.Button
, где это можно сделать напрямую.
У меня была похожая проблема. Я разрабатываю приложение, которое должно работать как на MacOS, так и на Windows.
Проблема: Я хотел создать кнопку из изображения, которая должна работать на обеих платформах. Однако Tkinter.Button
не работал на MacOS, а Tkmacosx.Button
имел нежелательное поведение.
Я опубликую немного кода, но ответ очень прост: ttk.Button()
работает и там, и там.
Однако, когда я использую кнопку ttk
, нет анимации движения при нажатии на кнопку. Когда все границы убраны и разные цвета фона заданы одинаковым цветом, кнопка не двигается, что не дает пользователю подтверждения о том, что кнопка была нажата.
Чтобы это исправить, мы свяжем нажатие и отпускание кнопки с их собственными методами. Оба метода будут просто смещать кнопку на +1 пиксель по x и y, а отпускание возвращать кнопку на исходную позицию.
class Root(bootstrap.Window):
"""
Основной интерфейс, состоящий из кнопки импорта и индикатора системы отслеживания 'актуальности'
"""
def __init__(self):
super().__init__()
self.settings = UIOptions().settings
# Конфигурация окна
self.title("Автоматизированный менеджер расходов")
self.option_add("*tearOff", False)
self.geometry("1000x700")
self.resizable(False, False)
self.config(background='dark grey')
# Кнопка с изображением стрелки
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' (активное) — когда мышь наводится на виджет, с тем же цветом, что и цвет фона главного окна ('active', 'dark grey')
. Это предотвращает изменение цвета виджета при наведении, так как он просто меняется на тот же цвет, который уже был фоном.
Этот код работает идеально как на MacOS, так и на Windows.
Надеюсь, это поможет!
Как установить pip на macOS или OS X?
Ошибка bash: команда pip не найдена
Цветовая палитра для Tkinter и Tix
Python: ImportError: lxml не найден, пожалуйста, установите его
Как предотвратить сжатие Frame в Tkinter под содержимое?