0
votes

I'd like to get as "modern" a look as possible with tkinter, possibly with the ttk addition. Modern buttons, pulldown boxes etc are often completely flat against the background with no border whatsoever. I've tried things like

ttk.Style().configure("TCombobox", padding=4, relief="flat",borderwidth = 
0,shiftrelief = 0 )

and the like, but nothing seems to remove the border. Is there something I'm missing? Ideally, for example, the "buttons" would look just like the buttons on the top of this very frame one types in on StackOverflow: just a symbol with transparent background and no border

2
Have you tried using the button from tkinter instead of ttk? - Bryan Oakley
I hadn't considered that because tkinter doesn't have a combobox, which I need (plenty) of. Can all tkinter (not ttk) widgets be "flattened" (no border, no relief etc)? Maybe I could workaround the combobox issue. - user3486991
You can use both tkinter and ttk widgets in the same application. Generally speaking, tkinter widgets are much more configurable than ttk widgets (or at least, more easily configured). - Bryan Oakley

2 Answers

0
votes

Add a non-dynamic image of the button you want, then check the event.x and event.y attributes of a Button-1 click (mouse-press). Use these coordinates to determine whether or not the user clicked your "button".

0
votes

this script should help you see what is going on 'under the hood'

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
c = ttk.Combobox(root)
c.grid()

style = 'TCombobox'

s = ttk.Style()
elements = s.layout(style)

def get_element_details(elem, _dict, depth=1):
    print('%selement: %s' % (''.join(['\t' for s in range(depth)]), elem))
    for key in _dict:
        if key != 'children':
            print('%s%s: %s' % (''.join(['\t' for s in range(depth+1)]), key, _dict[key]))
    print('%soption: %s' % (''.join(['\t' for s in range(depth+1)]), s.element_options(elem)))
    if 'children' in _dict:
        for child, child_dict in _dict['children']:
            get_element_details(child, child_dict, depth+1)

print('element: %s' % style)
print('option: %s' % str(s.element_options(style)))
for elem, elem_dict in elements:
    get_element_details(elem, elem_dict)

so for the style given it loops through the layout for each of the child elements, and returns layout info and options for each recursively.

when running this for Combobox i get:

element: TCombobox
option: ()
    element: Combobox.field
        sticky: nswe
        option: ()
        element: Combobox.downarrow
            side: right
            sticky: ns
            option: ()
        element: Combobox.padding
            expand: 1
            sticky: nswe
            option: ('-padding', '-relief', '-shiftrelief')
            element: Combobox.focus
                expand: 1
                sticky: nswe
                option: ('-focusfill',)
                element: Combobox.textarea
                    sticky: nswe
                    option: ('-font', '-width')

however when i tried:

s.configure('Combobox.padding', relief='flat', shiftrelief='flat')

or

s.configure('TCombobox.padding', relief='flat', shiftrelief='flat')

on windows I didn't see a change in the borders, it may not be implemented in the python bindings.

Edit: also there is a library Pwm that builds widgets from other tkinter widgets, meaning that (with a fair bit of work) you can re style those sub widgets, but i find the combobox from Pwm looks worse than ttk's version