tkinter:如何将在一个类中定义的自定义ttk stylename应用于其他类

时间:2018-03-12 08:10:04

标签: python tkinter ttk

我想将类中定义的自定义样式名应用于其他类中的小部件。我该如何实现呢?

以下是供考虑的测试脚本。我想将样式名'page.TFrame''press.TButton'应用于班级Page1Page2

测试脚本:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# tkinter modules
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkFont


class App(ttk.Frame):


    def __init__(self, parent=None, *args, **options):
        # Extract key and value from **options using Python3 "pop" function:
        #   pop(key[, default])
        self.style = options.pop('style',ttk.Style())
        self.bg0   = options.pop('background1','light grey')
        self.bg1   = options.pop('background2','grey')
        self.fg0   = options.pop('fg_link','black')
        self.fg1   = options.pop('fg_text','white')
        self.font  = options.pop('font',tkFont.Font(family='Nimbus Roman No9 L',
                                 size='10', weight='normal'))

        # Initialise App Frame
        ttk.Frame.__init__(self, parent, style='self.TFrame')
        self.__setFont()
        self.__setStyle()
        self.__createPages(parent)


    def __setFont(self):
        """Set the fonts to be used to build the App GUI."""
        self.fontTitle = self.font.copy()
        self.fontTitle.config(size='30')
        self.font.config(size='13')


    def __setStyle(self):
        """Customise ttk styles""" 
        ## LoginPanel styles
        self.style.configure('self.TFrame', background='pink')
        self.style.configure('page.TFrame', background=self.bg0)
        self.style.configure('press.TButton', font=self.fontTitle,
                             background=self.bg0, foreground=self.fg0,
                             relief='raised')


    def __createPages(self, parent):
        """Create Login and NewUser pages."""
        self._frames = {}
        for F in (Page1, Page2):
            page_name = F.__name__
            frame = F(parent=self)
            self._frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.showFrame("Page1")

        parent.rowconfigure(0, weight=1)
        parent.columnconfigure(0, weight=1)


    def showFrame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self._frames[page_name]
        frame.tkraise()



class Page1(ttk.Frame):

    def __init__(self, parent):
        ttk.Frame.__init__(self, parent, style='What to write here?')

        b1 = ttk.Button(self, text='Page 1',,
                        style='What to write here?')
        b1 .grid(row=0, column=0, sticky='nsew')

        b2 = ttk.Button(self, text='Goto Page 2?',
                        command=lambda: parent.showFrame("Page2"))
        b2 .grid(row=1, column=0, sticky='nsew')


class Page2(ttk.Frame):

    def __init__(self, parent):
        ttk.Frame.__init__(self, parent, style='What to write here?')

        b1 = ttk.Button(self, text='Page 2',
                        style='What to write here?')
        b1.grid(row=0, column=0, sticky='nsew')

        b2 = ttk.Button(self, text='Goto Page 1?',
                        command=lambda: parent.showFrame("Page1"))
        b2 .grid(row=1, column=0, sticky='nsew')


if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('400x350+300+300')
    BG1 = 'blue'
    BG0 = 'lightblue'
    FG0 = 'white'
    FG1 = 'light blue'

    app = App(root, background1=BG0, background2=BG1,
                  fg_link=FG1, fg_text=FG0)
    app.grid(row=0, column=0, sticky='nsew')

    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    root.mainloop()

1 个答案:

答案 0 :(得分:0)

我终于想通了,而且令人惊讶的答案很简单。

答案:我只需要将包含我想要使用的自定义样式名称的style属性参数传递给需要使用这些样式名称的其他类。在我的脚本中,需要传递的属性参数是self.style。希望这个答案可以帮助其他人有同样的需求。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# tkinter modules
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkFont


class App(ttk.Frame):


    def __init__(self, parent=None, *args, **options):
        # Extract key and value from **options using Python3 "pop" function:
        #   pop(key[, default])
        self.style = options.pop('style',ttk.Style())
        self.bg0   = options.pop('background1','light grey')
        self.bg1   = options.pop('background2','grey')
        self.fg0   = options.pop('fg_link','black')
        self.fg1   = options.pop('fg_text','white')
        self.font  = options.pop('font',tkFont.Font(family='Nimbus Roman No9 L',
                                 size='10', weight='normal'))

        # Initialise App Frame
        ttk.Frame.__init__(self, parent, style='self.TFrame')
        self.__setFont()
        self.__setStyle()
        self.__createPages(parent)


    def __setFont(self):
        """Set the fonts to be used to build the App GUI."""
        self.fontTitle = self.font.copy()
        self.fontTitle.config(size='30')
        self.font.config(size='13')


    def __setStyle(self):
        """Customise ttk styles""" 
        ## LoginPanel styles
        self.style.configure('self.TFrame', background='pink')
        self.style.configure('page.TFrame', background=self.bg0)
        self.style.configure('press.TButton', font=self.fontTitle,
                             background=self.bg1, foreground=self.fg0,
                             relief='raised')


    def __createPages(self, parent):
        """Create Login and NewUser pages."""
        self._frames = {}
        for F in (Page1, Page2):
            page_name = F.__name__
            frame = F(parent=self, style=self.style) #pass style attribute
            self._frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.showFrame("Page1")

        parent.rowconfigure(0, weight=1)
        parent.columnconfigure(0, weight=1)


    def showFrame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self._frames[page_name]
        frame.tkraise()



class Page1(ttk.Frame):

    def __init__(self, parent, style): #added `style` argument
        ttk.Frame.__init__(self, parent, style='page.TFrame') #call the stylename

        b1 = ttk.Button(self, text='Page 1', style='press.TButton') #call the stylename
        b1 .grid(row=0, column=0, sticky='nsew')

        b2 = ttk.Button(self, text='Goto Page 2?',
                        command=lambda: parent.showFrame("Page2"))
        b2 .grid(row=1, column=0, sticky='nsew')


class Page2(ttk.Frame):

    def __init__(self, parent, style): #added `style` argument
        ttk.Frame.__init__(self, parent, style='page.TFrame') #call the stylename

        b1 = ttk.Button(self, text='Page 2', style='press.TButton') #call the stylename
        b1.grid(row=0, column=0, sticky='nsew')

        b2 = ttk.Button(self, text='Goto Page 1?',
                        command=lambda: parent.showFrame("Page1"))
        b2 .grid(row=1, column=0, sticky='nsew')


if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('400x350+300+300')
    BG1 = 'blue'
    BG0 = 'lightblue'
    FG0 = 'white'
    FG1 = 'light blue'

    app = App(root, background1=BG0, background2=BG1,
                  fg_link=FG1, fg_text=FG0)
    app.grid(row=0, column=0, sticky='nsew')

    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    root.mainloop()