如何修改ttk Combobox字体?

5

我一直在尝试使用传统的方式修改 ttk.Combobox 小部件的字体。

text_font = ('Courier New', '10')
mycombobox = Combobox(font = text_font)
mycombobox.pack()

但字体并没有真正改变……

我也尝试使用 ttk.Style,但仍然没有任何反应。

text_font = ('Courier New', '10')
ttk_style = ttk.Style()
ttk_style.configure('App.TCombobox', font=text_font)

mycombobox = Combobox(style = "App.TCombobox")
mycombobox.pack()

有没有一种方法可以控制字体?我想要改变EntryListBox的字体。

一个类似的问题在2015年之前已经被问过了,并在那里得到了回答。 - Sun Bear
1个回答

8

这是一个非常奇怪的行为,因为在我的电脑上它能够正常工作:

try:
    import tkinter as tk
    import tkinter.ttk as ttk
except ImportError:
    import Tkinter as tk
    import ttk

import random
import string


def insert_something_to_combobox(box):
    box['values'] = [gen_key() for _ in range(10)]


def gen_key(size=6, chars=string.ascii_uppercase + string.digits):
    # just to generate some random stuff
    return ''.join(random.choice(chars) for _ in range(size))


root = tk.Tk()
text_font = ('Courier New', '10')
main_frame = tk.Frame(root, bg='gray')                  # main frame
combo_box = ttk.Combobox(main_frame, font=text_font)    # apply font to combobox
entry_box = ttk.Entry(main_frame, font=text_font)       # apply font to entry
root.option_add('*TCombobox*Listbox.font', text_font)   # apply font to combobox list
combo_box.pack()
entry_box.pack()
main_frame.pack()

insert_something_to_combobox(combo_box)

root.mainloop()

下拉框输入框

对于特定的下拉框,我们可以指定一个字体,因为我们可以依赖于ttk::combobox::PopdownWindow函数:

...
class CustomBox(ttk.Combobox):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bind('<Map>', self._handle_popdown_font)

    def _handle_popdown_font(self, *args):
        popdown = self.tk.eval('ttk::combobox::PopdownWindow %s' % self)
        self.tk.call('%s.f.l' % popdown, 'configure', '-font', self['font'])
...
root = tk.Tk()
text_font = ('Courier New', '10')
main_frame = tk.Frame(root, bg='gray')                  # main frame
combo_box = CustomBox(main_frame, font=text_font)       # apply font to combobox
entry_box = ttk.Entry(main_frame, font=text_font)       # apply font to entry
...
root.mainloop()

然而,这个CustomBox缺乏功能,因为当组合框小部件被映射时,弹出框的字体被配置了一次,因此稍后对字体的任何配置都不会为弹出框配置该选项。
让我们尝试覆盖默认的配置方法:
class CustomBox(ttk.Combobox):
    def __init__(self, *args, **kwargs):
        #   initialisation of the combobox entry
        super().__init__(*args, **kwargs)
        #   "initialisation" of the combobox popdown
        self._handle_popdown_font()

    def _handle_popdown_font(self):
        """ Handle popdown font
        Note: https://github.com/nomad-software/tcltk/blob/master/dist/library/ttk/combobox.tcl#L270
        """
        #   grab (create a new one or get existing) popdown
        popdown = self.tk.eval('ttk::combobox::PopdownWindow %s' % self)
        #   configure popdown font
        self.tk.call('%s.f.l' % popdown, 'configure', '-font', self['font'])

    def configure(self, cnf=None, **kw):
        """Configure resources of a widget. Overridden!

        The values for resources are specified as keyword
        arguments. To get an overview about
        the allowed keyword arguments call the method keys.
        """

        #   default configure behavior
        self._configure('configure', cnf, kw)
        #   if font was configured - configure font for popdown as well
        if 'font' in kw or 'font' in cnf:
            self._handle_popdown_font()

    #   keep overridden shortcut
    config = configure

这个类会生成一个响应更快的下拉列表实例。


2
你的代码确实在工作 - 主要区别在于 root.option_add('*TCombobox*Listbox.font', text_font) 语句,它会操作应用程序中所有组合框的列表框字体。虽然这样可以工作,但会破坏应用程序中的其他 GUI 元素。 - NirMH
1
@NirMH 是的,我知道。所以你的问题特别关于列表框字体。然而,根据 ttk.combobox 文档,combobox 利用预装的 Listbox 作为其下拉元素,因此 'option' 命令目前需要设置列表框的选项。所以我认为在 Python 中无法仅更改指定的组合框列表框,但他们展示了使用 tcl 的方法!可惜,我在 tk 中未能成功 evalcall 这些命令。 - CommonSense
1
这是只有我一个人还是对于刚开始学习Tkinter的人来说,这一定是一个重要的“啥?”时刻。在那之前,一切看起来都很有前途。 - z33k
1
@o'rety,我稍微更新了我的答案,并提供了特定组合框的解决方案。它仍然是一个主要的“啥”吗? - CommonSense
1
@CommonSense:我不想让这个评论区被删除并移到聊天室,所以我只想说它不再是递归的了,因为你在同时纠正了它(第8行调用了“combo_box”而非“self”)。至于我的问题,我很确定它不是由我的代码中的任何特殊性引起的,并且确信这是一个普遍的情况。现在,回到主题——你的解决方案有效,它可以合并到官方的Tkinter代码中吗?更改ttk.Combobox上的字体将仅起作用,并且未来用户无需在SO上寻求帮助。 - z33k
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接