How to create arrow in a tkinter.ttk.Button and control it's size?

ε祈祈猫儿з 提交于 2019-12-12 18:39:32

问题


I would like to create ttk.button with an arrow in it and have the arrow size changable.

I discovered 'TButton' inherently contains StyleNames TButton.leftarrow which is not exposed by the ttk.Style().layout().

Questions: (1) How do I activate these StyleNames? (2) How do I control the size of .leftarrow? I notice it has a arrowsize option . How do I use it?

import tkinter as tk
import tkinter.ttk as ttk

class App(ttk.Frame):

        def __init__(self, parent):
            ttk.Frame.__init__(self, parent)
            self.parent = parent
            self.setStyle()
            self.setWidget()

        def setStyle(self):
            style = ttk.Style()
            print('Left.TButton layout are:', style.layout('Left.TButton'))
            print("Left.TButton.leftarrow style.element_options: ",
                  style.element_options('Left.TButton.leftarrow'))

            style.configure('Left.TButton', background='yellow')
            style.configure('Left.TButton.leftarrow', background='white',
                            arrowsize=20)

        def setWidget(self):
            self.lbutton = ttk.Button(self.parent, style='Left.TButton')
            self.lbutton2 = ttk.Button(self.parent, style='Left.TButton.leftarrow')
            self.lbutton.pack()
            self.lbutton2.pack()


    if __name__ == '__main__':
        root = tk.Tk()
        root.title('Test')
        root.geometry('200x50')
        app = App(root)
        app.pack(expand=1, fill='both')

回答1:


After quite a lot of attempts and closer studies of the ttk documentations, I discovered the following:

  1. To create a arrow in the button, I have to declare a arrow element as the child of the focus element in the layout of the custom style that is to be used for the ttk.Button() widget. To do this, I needed to use the ttk.Style().layout() method.
  2. The size of the arrow is dependent on the font size of the label element. Therefore, a label element had to be declared in layout of the style TButton. The arrowsize option of the arrowleft element did not seem to work. I have commented out this line of code which did not work. However, the arrowcolor option of the leftarrow element does work. To adjust the label element's font size, the ttk.Style().configuration method was used.

Approach 2 in Test Script demonstrates the solution to my question.

Test Code:

import tkinter as tk
import tkinter.ttk as ttk


class App(ttk.Frame):

    def __init__(self, parent):
        ttk.Frame.__init__(self, parent)
        self.parent = parent
        self.setStyle()
        self.setWidget()

    def setStyle(self):
        style = ttk.Style()
        print('\nDefault TButton layout:')
        print(style.layout('TButton'))

        print ('\nTButton Elements and their options:')
        print("border options: ", style.element_options('Button.border'))
        print("focus options: ",  style.element_options('Button.focus'))
        print("padding options: ",style.element_options('Button.padding'))
        print("label options: ",  style.element_options('Button.label'))
        print("arrow options: ",  style.element_options('Button.arrow'))

        print ('\nElement TButton.label and its options:')
        print("compound: ",  style.lookup('Button.label', 'compound'))
        print("space: ",     style.lookup('Button.label', 'space'))
        print("text: ",      style.lookup('Button.label', 'text'))
        print("font: ",      style.lookup('Button.label', 'font'))
        print("foreground: ",style.lookup('Button.label', 'foreground'))
        print("underline: ", style.lookup('Button.label', 'underline'))
        print("width: ",     style.lookup('Button.label', 'width'))
        print("anchor: ",    style.lookup('Button.label', 'anchor'))
        print("justify: ",   style.lookup('Button.label', 'justify'))
        print("wraplength: ",style.lookup('Button.label', 'wraplength'))
        print("embossed: ",  style.lookup('Button.label', 'embossed'))
        print("image: ",     style.lookup('Button.label', 'image'))
        print("stipple: ",   style.lookup('Button.label', 'stipple'))
        print("background: ",style.lookup('Button.label', 'background'))

        print ('\nElement TButton.arrow and its options:')
        print("background: ", style.lookup('Button.arrow', 'background'))
        print("relief: ",     style.lookup('Button.arrow', 'relief'))
        print("borderwidth: ",style.lookup('Button.arrow', 'borderwidth'))
        print("arrowcolor: ", style.lookup('Button.arrow', 'arrowcolor'))
        print("arrowsize: ",  style.lookup('Button.arrow', 'arrowsize'))

        #Define style Default.TButton with yellow background
        style.configure('Default.TButton', background='yellow')
        #Change the 2 options of the "label" element in its style's layout  
        style.configure('Default.TButton.label', foreground='red')
        style.configure('Default.TButton.label', borderwidth=20)
        print ('\nElement Default.TButton.label and its options (after configuration):')
        print("background: ",  style.lookup('Default.TButton.border', 'background'))
        print("borderwidth: ", style.lookup('Default.TButton.border', 'borderwidth'))

        #Approach 1
        #==========
        # Define style Left.TButton to show the following elements: leftarrow,
        #  padding, label 
        style.layout(
            'Left1.TButton',[
                ('Button.focus', {'children': [
                    ('Button.leftarrow', None),
                    ('Button.padding', {'sticky': 'nswe', 'children': [
                        ('Button.label', {'sticky': 'nswe'}
                         )]}
                     )]}
                 )]
            )
        #Change 3 options of the "arrow" element in style "Left.TButton"
        style.configure('Left1.TButton.leftarrow',
                        background='white',
                        borderwidth=10,
                        arrowsize=20)
        print('\nElement TButton.arrow and its options (after changing):')
        print("background: ",  style.lookup('Left1.TButton.arrow','background'))
        print("borderwidth: ", style.lookup('Left1.TButton.arrow','borderwidth'))
        print("arrowsize: ",   style.lookup('Left1.TButton.arrow','arrowsize'))

        #Approach 2
        #==========
        style.layout(
            'Left2.TButton',[
                ('Button.focus', {'children': [
                    ('Button.leftarrow', None),
                    ('Button.padding', {'sticky': 'nswe', 'children': [
                        ('Button.label', {'sticky': 'nswe'}
                         )]}
                     )]}
                 )]
            )

        style.configure('Left2.TButton',font=('','20','bold'), width=1, arrowcolor='white')
        #style.configure('Left2.TButton', width=1, arrowcolor='white', arrowsize='20')
        #option arrowsize does not work


    def setWidget(self):
        self.lbutton = ttk.Button(self.parent, style='Default.TButton',
                                  text='Default.TButton')
        self.lbutton1 = ttk.Button(self.parent, style='Left1.TButton',
                                   text='Left1.Button')
        self.lbutton2 = ttk.Button(self.parent, style='Left2.TButton',
                                   text='')
        self.lbutton.pack()
        self.lbutton1.pack()
        self.lbutton2.pack()


if __name__ == '__main__':
    root = tk.Tk()
    root.title('Test')
    root.geometry('200x100')
    app = App(root)
    app.pack(expand=1, fill='both')


来源:https://stackoverflow.com/questions/48770877/how-to-create-arrow-in-a-tkinter-ttk-button-and-control-its-size

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