6

当 ttk.Combobox 为只读且未获得焦点时,其文本背景变为白色,与灰色字段背景不同,并使组合框看起来很难看:

例子

所需的样式将是第二个样式。如何使组合框像那样工作?

4

2 回答 2

7

解决方案是像这样更改 ttk 样式:

s = ttk.Style()
s.map("TCombobox",
    selectbackground=[
        ('!readonly', '!focus', 'SystemWindow'),
        ('readonly', '!focus', 'SystemButtonFace'),
        ],
    )

这会全局更改组合框的行为。在下面的演示中(从中制作了问题的屏幕截图),我为运行良好的组合框定义了一个自定义样式作为“Alt.TCombobox”并使用它:

# cboxdemo.py by Adam Szieberth (2013)
# Python 3.3.0

"""Read-only Ttk.Combobox style demo module.

The style of the second combobox has been slightly modified to
make text background match with combobox background when out of
focus.

In read-only state (which is default) you can notice that text
background gets white in the first (original styled) combobox
when focus moves towards. Second combobox looks nice then.

With the button you can test that the two works exactly the same
in writeable state.
"""

from random import randint
from tkinter import Button, Frame, StringVar, Tk
from tkinter.ttk import Combobox, Style

class App(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.state = None
        self.style = Style()
        self.style.map("Alt.TCombobox",
            selectbackground=[
                ('!readonly', '!focus', 'SystemWindow'),
                ('readonly', '!focus', 'SystemButtonFace'),
                ],
            )
        self.button = Button(self, text="Change state!",
            command=self.switch)
        self.cbox1var, self.cbox2var = StringVar(), StringVar()
        self.cbox1 = Combobox(self,
            exportselection=0,
            values=["sex", "sleep", "eat", "drink", "dream",],
            textvariable=self.cbox1var,
            )
        self.cbox1.bind('<<ComboboxSelected>>', self.bfocus)
        self.cbox1.current(1)
        self.cbox2 = Combobox(self,
            exportselection=0,
            values=["fear", "clarity", "power", "old age",],
            style="Alt.TCombobox",
            textvariable=self.cbox2var,
            )
        self.cbox2.bind('<<ComboboxSelected>>', self.bfocus)
        self.cbox2.current(3)
        self.cbox1.pack()
        self.cbox2.pack()
        self.button.pack()
        self.switch()

    def bfocus(self, *args):
        if randint(0,1):
            self.button.focus()
            print('Focus moved!')
        else:
            print('Focus stayed.')

    def switch(self):
        if self.state == ['readonly']:
            self.state = ['!readonly']
            print('State is writeable!')
        else:
            self.state = ['readonly']
            print('State is read-only!')
        self.cbox1.state(self.state)
        self.cbox2.state(self.state)

if __name__ == "__main__":
    root = Tk()
    root.title('ttk.Combobox styling')
    App(root).pack()
    root.mainloop()
于 2013-09-04T09:46:26.430 回答
1

另一种方法可能如下:

from tkinter.ttk import Combobox, Style

style = Style()
style.theme_create('custom_style',
                   parent='default',
                   settings={'TCombobox':
                             {'configure':
                              {'selectforeground': 'black',
                               'selectbackground': 'white'}
                              }
                             }
                   )
style.theme_use('custom_style')

现在您创建一个简单的组合框。

cb = Combobox(frame1, state='readonly')
cb['values'] = [
    'Please select',
    'Option 1',
    'Option 2',
    'Option 3'
]
cb.current(0)
cb.bind('<<ComboboxSelected>>', my_function_to_exec)
cb.grid(row=0, column=0, sticky='w')

这不会保持选中的文本。将其作为“主题”完成后,这将适用于所有组合框。

于 2020-01-15T16:30:37.627 回答