How to get FLAT relief Entry widget in python ttk?

霸气de小男生 提交于 2020-01-05 08:25:26

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/44383730/how-to-get-flat-relief-entry-widget-in-python-ttk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!