简体   繁体   中英

How to get FLAT relief Entry widget in python ttk?

I am writing a GUI FTP client app in python ttk. I can't seem to get the text Entries the way I wanted them to. 在此输入图像描述

The text Entries have the "SUNKEN" effect. I want to adjust the height and get the text entries to have a "FLAT" look, more like this program:

在此输入图像描述
I got the buttons to look flat from here , I am struggling to get the Entries to look flat.
How do I get the Entries to look flat?

I don't want a tk solution, I know how to set relief FLAT in tk.

Trivia:

Appereance of ttk widgets heavily depends on theme in use and/or platform. On windows I can reproduce this depressive gray style with a classic theme, so let's assume that this theme in use. List of themes you can find here (note the 'clam' theme, wich is most similar to your wishes), just if you wonder.

Next stop, our layout or, in other words, a structure of widget's theme. You can easily print this structure to see available options. Enough words, let's try a structure of an ttk.Entry widget.

>>> print(s.layout('TEntry'))

#   formatted result, actual result is one-line string
[('Entry.highlight', {
    'sticky': 'nswe',
    'children': [(
        'Entry.field', {
            'sticky': 'nswe',
            'children': [(
                'Entry.padding', {
                    'sticky': 'nswe',
                    'children': [(
                        'Entry.textarea', {
                            'sticky': 'nswe'})]
                })],
            'border': '1'})]
})]

As you can see , noone of structure elements has a relief option, hence relief='flat' has no effect on our entry!

>>> print(s.element_options('Entry.field'))
('-bordercolor', '-lightcolor', '-darkcolor', '-fieldbackground')

Workaround:

However, we can edit the layout of desired widget, and replace one element with another, wich able to recognize a relief option (note a removed Entry.field , replaced with an Entry.border ).

So try out this little snippet:

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

#   root
root = tk.Tk()

#   declare style variable
s = ttk.Style()
#   assume that classic theme in use
s.theme_use('classic')

#   configure relief
s.configure('SOExample.TEntry', relief='flat')

#   lets try to change this structure
s.layout('SOExample.TEntry', [
    ('Entry.highlight', {
        'sticky': 'nswe',
        'children':
            [('Entry.border', {
                'border': '1',
                'sticky': 'nswe',
                'children':
                    [('Entry.padding', {
                        'sticky': 'nswe',
                        'children':
                            [('Entry.textarea',
                              {'sticky': 'nswe'})]
                    })]
            })]
    })])

#   let's find some differences between this two
print(s.layout('SOExample.TEntry'))
print(s.layout('TEntry'))

#    packing
frame1 = tk.Frame(root)
label1 = tk.Label(frame1, text='Flat Entry')
entry1 = ttk.Entry(frame1, style='SOExample.TEntry')
label1.pack()
entry1.pack()
frame1.pack(side='left')

frame2 = tk.Frame(root)
label2 = tk.Label(frame2, text='Default Entry')
entry2 = ttk.Entry(frame2)
label2.pack()
entry2.pack()
frame2.pack(side='right')

#   mainloop
root.mainloop()

...and final appereance is:

不活跃 活性

Also, on my machine default theme is vista and there I can't even recognize an entry: 远景

And also a structure of an Entry depends on theme, so with vista it's:

#   formatted result, actual result is one-line string
[('Entry.field', {
    'sticky': 'nswe',
    'children': [(
        'Entry.background', {
            'sticky': 'nswe',
            'children': [(
                'Entry.padding', {
                    'sticky': 'nswe',
                    'children': [(
                        'Entry.textarea', {
                            'sticky': 'nswe'})]
                })]
        })]
})]

...and if we replace a field with border element in this structure, the appearence is very close to your demands (also try groove relief in this case):

远景

Conclusion:

Unfortunately, this widget will lack options of field and border color, so another option is create own element for this purpose, but that is another question.

So, basicly I tryied to answer not "how to workaround this" , but "why a relief has no effect on Entry" , anyway as you can see, a flat relief for an Entry is achievable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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