简体   繁体   English

ttk 入口背景色

[英]ttk Entry background colour

How exactly do I change the background colour of an Entry widget from ttk?如何从 ttk 更改 Entry 小部件的背景颜色? What I have so far is:到目前为止我所拥有的是:

        self.estyle = ttk.Style()
        self.estyle.configure("EntryStyle.TEntry", background='black')
        self.estyle.map("EntryStyle.TEntry",
                        foreground=[('disabled', 'yellow'),
                                    ('active', 'blue')],
                        background=[('disabled', 'magenta'),
                                    ('active', 'green')],
                        highlightcolor=[('focus', 'green'),
                                        ('!focus', 'red')])
        self.urlentry_v = StringVar()
        self.urlentry = ttk.Entry(self.input_frame, style="EntryStyle.TEntry",
                                  textvariable=self.urlentry_v)

Basically, I've changed everything I can think of, but the text entry remains stubbornly white.基本上,我已经改变了我能想到的一切,但文本条目仍然顽固地保持白色。

Additionally, is there a way of changing the border colour?另外,有没有办法改变边框颜色?

I've figured it out, after a lot of digging.经过大量挖掘,我已经弄清楚了。 As hard as I had to search to figure this out, I suppose others would benefit from this:尽管我不得不努力寻找解决方案,但我想其他人会从中受益:

The standard style applied to ttk.Entry simply doesn't take a fieldbackground option, which would be what changes the colour of the text entry field.应用于 ttk.Entry 的标准样式根本不采用 fieldbackground 选项,这将改变文本输入字段的颜色。 The solution is this to create a new element that does respond to the option.该解决方案是这样的,以创建一个具有响应的选项的新元素。

from tkinter import *
from tkinter import ttk

root_window = Tk()

estyle = ttk.Style()
estyle.element_create("plain.field", "from", "clam")
estyle.layout("EntryStyle.TEntry",
                   [('Entry.plain.field', {'children': [(
                       'Entry.background', {'children': [(
                           'Entry.padding', {'children': [(
                               'Entry.textarea', {'sticky': 'nswe'})],
                      'sticky': 'nswe'})], 'sticky': 'nswe'})],
                      'border':'2', 'sticky': 'nswe'})])
estyle.configure("EntryStyle.TEntry",
                 background="green", 
                 foreground="grey",
                 fieldbackground="black")
entry_v = StringVar()
entry = ttk.Entry(root_window, style="EntryStyle.TEntry", textvariable=entry_v)
entry.pack(padx=10, pady=10)

Unfortunately, it appears that the only way to change the border colour is to either give it zero border width and nest it in a frame that acts as its border, or to define a new layout item that uses an image as a border.不幸的是,似乎改变边框颜色的唯一方式是要么给它零边框宽度和巢它充当其边界,或定义使用图像作为边界新布局项目的帧。

Additionally, note that the only thing the background controls is the very tiny corner space;此外,请注意,背景控制的唯一内容是非常小的角落空间; if you squint closely, you can see a single pixel of green in each corner.如果你仔细眯眼,你会看到每个角落都有一个绿色像素。

To use an image as a border, you can do this:要将图像用作边框,您可以这样做:

img2 = PhotoImage("entryBorder", data="""
        R0lGODlhHQAdAOMNAAAAAAQGCAgLERkfLR0mODBFZTFFZTNIajtTezxTez1XgD5XgU
        Fch////////////ywAAAAAHQAdAAAEbHCQg5i9OGt0iFRaKGLKxBgCoK5s6woGc4Cp
        a9+AwFQM7ruYn1AVHP6KRhwyaVsyW87nKioFUKXXZ5a5TXaN32FYOD5eqsAzmlX2tZ
        XqNZGxYATkgAD9wCjUqgIFMgR1I4YZCx4TCYeGCR0DEQA7""")

oestyle = ttk.Style()
oestyle.element_create("blueborder", "image", "entryBorder",
                                   border=3, sticky="nsew")
oestyle.layout("OEntryStyle.TEntry",
               [('Entry.blueborder', {'children': [(
                   'Entry.padding', {'children': [(
                     'Entry.textarea', {'sticky': 'nswe'})],
                      'sticky': 'nswe'})], 'sticky': 'nswe'})])
oestyle.configure("OEntryStyle.TEntry",
                 background="black",
                  foreground="grey")
oentry_v = StringVar()
oentry = ttk.Entry(root_window, style="OEntryStyle.TEntry", textvariable=oentry_v)
oentry.pack(padx=10, pady=10)

The string of characters is generated by feeding an image of the borders I want as a gif to字符串是通过将我想要的边框图像作为 gif 提供给来生成的

import base64

with open('otherframeBorder.gif', 'rb') as f:
    encoded = base64.encodestring(f.read())
    print(encoded.decode('latin1'))

I liked your approach in using an image, but I think it's a tad tedious to go through the process of importing an image as a base64 encoded string when PhotoImage allows for creating images on the fly.我喜欢你使用图像的方法,但我认为当 PhotoImage 允许动态创建图像时,将图像作为 base64 编码字符串导入的过程有点乏味。 I've expanded on the concept to make a class that handles making such an 'image' to use as a border, and it takes any arguments a regular ttk.Entry widget would.我已经扩展了这个概念来制作一个类来处理制作这样一个“图像”以用作边框,并且它接受常规ttk.Entry小部件会使用的任何参数。 Note that I'm only able to test on Windows 10, but this should be platform independent.请注意,我只能在 Windows 10 上进行测试,但这应该与平台无关。

from tkinter import ttk
import tkinter as tk

class BorderedEntry(ttk.Entry):
    def __init__(self, root, *args, bordercolor, borderthickness=1,
                 background='white', foreground='black', **kwargs):
        super().__init__(root, *args, **kwargs)
        # Styles must have unique image, element, and style names to create
        # multiple instances. winfo_id() is good enough
        e_id = self.winfo_id()
        img_name = 'entryBorder{}'.format(e_id)
        element_name = 'bordercolor{}'.format(e_id)
        style_name = 'bcEntry{}.TEntry'.format(e_id)
        width = self.winfo_reqwidth()
        height = self.winfo_reqheight()
        self.img = tk.PhotoImage(img_name, width=width, height=height)
        self.img.put(bordercolor, to=(0, 0, width, height))
        self.img.put(background, to=(borderthickness, borderthickness, width -
                     borderthickness, height - borderthickness))

        style = ttk.Style()
        style.element_create(element_name, 'image', img_name, sticky='nsew',
                             border=borderthickness)
        style.layout(style_name,
                     [('Entry.{}'.format(element_name), {'children': [(
                      'Entry.padding', {'children': [(
                          'Entry.textarea', {'sticky': 'nsew'})],
                          'sticky': 'nsew'})], 'sticky': 'nsew'})])
        style.configure(style_name, background=background,
                        foreground=foreground)
        self.config(style=style_name)

root = tk.Tk()
bentry_red = BorderedEntry(root, bordercolor='red')
bentry_blue = BorderedEntry(root, bordercolor='blue')
bentry_red.grid(row=0, column=0, pady=(0, 5))
bentry_blue.grid(row=1, column=0)
root.mainloop()

I have found simpler way to change Entry background color.我找到了更简单的方法来更改条目背景颜色。 Using:使用:

fieldbackgroud="your_color" fieldbackground="your_color"

entry_style = Style()

entry_style.configure('style.TEntry', 

            fieldbackground="black", 

            foreground="white"           

           )

e = Entry(root, width=80, style='style.TEntry', font='sans 15 bold')

e.focus_force()

e.grid(row=0, column=0, columnspan=4, padx=0, pady=0, sticky="nsew")

The code below works fine for me on an iMac with Python 3.3.2 and Tcl/Tk 8.5.下面的代码在带有 Python 3.3.2 和 Tcl/Tk 8.5 的 iMac 上对我来说很好用。 Also works on a Mac G5 with Python 3.3.2 and Tcl/Tk 8.4.也适用于带有 Python 3.3.2 和 Tcl/Tk 8.4 的 Mac G5。 It does NOT work on Windows XP sp3 with Python 3.3.2 and Tcl/Tk 8.5.它不适用于使用 Python 3.3.2 和 Tcl/Tk 8.5 的 Windows XP sp3。 In the latter case, the entry background, as it did for you, remains stubbornly white.在后一种情况下,入口背景,就像它为您所做的那样,仍然顽固地保持白色。

Here's why it doesn't change colors in Windows.这就是它在 Windows 中不改变颜色的原因。 The example there is also in Tcl. Tcl 中也有这个例子。

https://groups.google.com/forum/#!topic/comp.lang.tcl/RmbiFrTFCdw https://groups.google.com/forum/#!topic/comp.lang.tcl/RmbiFrTFCdw

I worked on your nonworking example a little, and it also works on my Mac, except that I get no response from "active" and "focus" in the map.我对您的非工作示例进行了一些处理,它也适用于我的 Mac,只是我没有从地图中的“活动”和“焦点”中得到任何响应。 Nothing happens there.那里什么也没有发生。

Some of this is still very mysterious to me.其中一些对我来说仍然很神秘。 It looks like there is some help here:看起来这里有一些帮助:
http://wiki.tcl.tk/38127 http://wiki.tcl.tk/38127
http://wiki.tcl.tk/37973 http://wiki.tcl.tk/37973
but it's in Tcl and assumes some knowledge on the part of the viewer just to read it.但它是在 Tcl 中的,并且假设观众有一些知识只是为了阅读它。

Here's my example that I mentioned at the beginning of this post:这是我在本文开头提到的示例:

from tkinter import *
from tkinter.ttk import *


class App(Frame):
    def __init__(self, parent):
        super().__init__(parent)
        s = Style()
        s.configure('Pink.TEntry', background='hot pink')
        self.e1 = Entry(self)
        print("Our entry is of type {}".format(type(self.e1)))
        b = Button(self, text="Switch Styles", command=self.switch)
        self.pink = False

        self.e1.pack()
        b.pack()

    def switch(self):
        if self.pink:
            print("going white", end="")
            self.e1["style"] = "TEntry"
        else:
            print("going pink", end="")
            self.e1["style"] = "Pink.TEntry"
        self.pink = not self.pink
        print("; style is now {}".format(self.e1["style"]))

root = Tk()
a = App(root)
a.pack()
root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM