0

Как изменить цвет фона или текста кнопки Tkinter на Mac OS X?

12

Я работаю над главами 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 ответ(ов)

0

Я думаю, что причина в том, что кнопки на Mac просто не поддерживают изменение фона и цвета текста. Как вы уже заметили, это не уникально для Tk.

0

Если вы столкнулись с проблемой, при которой не работает ваша кнопка, одним из быстрых способов решения может быть использование метки (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, чтобы добавить дополнительную логику, реагирующую на ваше конкретное событие.

0

Это сработало для меня:

self.gnuplot_bt = Button(
    self.run_but_container, text="Построить график с Gnuplot", font="Helvetica", command=self.gnuplot,
    highlightbackground="#8EF0F7", pady=2, relief=FLAT
)
0

Да, представленный вами код может изменить фон кнопки в 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, где это можно сделать напрямую.

0

У меня была похожая проблема. Я разрабатываю приложение, которое должно работать как на 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.

Надеюсь, это поможет!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь