2025, Oct 18 22:16
Почему текст в ttk.Combobox пропадает в теме clam и как это исправить
Исправляем баг темы clam в Tkinter: в readonly ttk.Combobox выбранный текст «исчезает» из‑за цвета foreground. Разбираем причину и даем стиль ttk.Style.map.
При стилизации ttk.Combobox в Tkinter с темой clam можно столкнуться с неожиданным UX-эффектом: после взаимодействия с выпадающим списком выбранный текст будто исчезает. Значение остаётся, но его не видно. В темах вроде alt этот эффект не проявляется, поэтому проблема выглядит специфичной для темы и кажется непоследовательной.
Воспроизведение проблемы
Ниже приведён пример readonly-Combobox под темой clam с белыми фонами. Во время взаимодействия выбранный пункт становится невидимым.
import tkinter as tk, tkinter.ttk as ttk
app = tk.Tk()
styler = ttk.Style(app)
styler.theme_use("clam")
styler.configure("TCombobox", fieldbackground="white", background="white")
styler.map("TCombobox", fieldbackground=[["readonly", "white"]], background=[["readonly", "white"]])
chooser = ttk.Combobox(app, state="readonly", values=("apples", "oranges", "bananas"))
chooser.set("apples")
chooser.pack(padx=40, pady=40)
app.mainloop()
Что на самом деле происходит
В теме clam цвет текста (foreground) по умолчанию для состояния readonly при наличии фокуса — белый. Если fieldbackground тоже белый, текст фактически сливается с полем. Отсюда и ощущение, что значение пропадает.
Исправление оформления
Решение — явно сопоставить читаемый цвет текста с нужным состоянием. Если установить чёрный foreground для Combobox в состояниях readonly и focus, текст снова будет виден.
import tkinter as tk, tkinter.ttk as ttk
app = tk.Tk()
styler = ttk.Style(app)
styler.theme_use("clam")
styler.configure("TCombobox", fieldbackground="white", background="white")
styler.map(
    "TCombobox",
    fieldbackground=[["readonly", "white"]],
    background=[["readonly", "white"]],
    foreground=[["readonly", "focus", "black"]]
)
chooser = ttk.Combobox(app, state="readonly", values=("apples", "oranges", "bananas"))
chooser.set("apples")
chooser.pack(padx=40, pady=40)
app.mainloop()
При желании можно задать цвет текста для readonly и без учёта фокуса.
Почему эта деталь важна
Тематические оформления интерфейса задают разумные значения по умолчанию, но ваши настройки могут незаметно конфликтовать с ними. В нашем случае простая смена фона «спрятала» текст из‑за сопоставления состояний, заданного темой. Понимание того, как работает ttk.Style.map и как взаимодействуют состояния вроде readonly и focus, помогает избежать визуальных регрессий и сохраняет читабельность виджета при разных сценариях взаимодействия.
Выводы
Переопределяя fieldbackground или другие визуальные свойства ttk‑виджетов, обязательно проверьте сопоставления для foreground — особенно для конкретных состояний, которые использует ваша тема. Небольшая явная карта состояний для foreground обеспечивает стабильную читабельность и убережёт от сюрпризов вроде «исчезающего» выбора в ttk.Combobox под темой clam.