Python style.map()在查询两次时返回不同的值

Python style.map()在查询两次时返回不同的值,python,python-3.x,tkinter,ttk,Python,Python 3.x,Tkinter,Ttk,我正在研究style.map()函数。我一直在阅读Tkinter的Python GUI编程,他提到如果调用style.map('Treeview')(或任何类型),它应该返回当前状态映射 现在,当我第一次运行它时,我得到: s = ttk.Style() s.map('Treeview') {'foreground': [('disabled', 'SystemGrayText'), ('!disabled', '!selected', 'SystemWindowText'), ('select

我正在研究style.map()函数。我一直在阅读Tkinter的Python GUI编程,他提到如果调用style.map('Treeview')(或任何类型),它应该返回当前状态映射

现在,当我第一次运行它时,我得到:

s = ttk.Style()
s.map('Treeview')
{'foreground': [('disabled', 'SystemGrayText'), ('!disabled', '!selected', 'SystemWindowText'), ('selected', 'SystemHighlightText')], 'background': [('disabled', 'SystemButtonFace'), ('!disabled', '!selected', 'SystemWindow'), ('selected', 'SystemHighlight')]}
这将返回具有预期状态和当前属性的元组

现在如果我再说一遍:

s.map('Treeview')
{'foreground': ['disabled', 'SystemGrayText', '!disabled !selected', 'SystemWindowText', 'selected', 'SystemHighlightText'], 'background': ['disabled', 'SystemButtonFace', '!disabled !selected', 'SystemWindow', 'selected', 'SystemHighlight']}
现在它只是一个状态/属性列表

我试着浏览文档,但在尝试这样做时有点迷失了方向。我注意到的一件事是,它调用了一个_splitdict函数,该函数最初为每个属性返回键/值对。当我打印出键/值对时,它看起来像:

-foreground (<string object: 'disabled'>, 'SystemGrayText', <string object: '!disabled !selected'>, 'SystemWindowText', <string object: 'selected'>, 'SystemHighlightText')
-background (<string object: 'disabled'>, 'SystemButtonFace', <string object: '!disabled !selected'>, 'SystemWindow', <string object: 'selected'>, 'SystemHighlight')

这是故意的吗?它是如何工作的?

我不能告诉你这是故意的,但我可以证明第二个版本不起作用。我做了一个简单的自定义主题。在这个主题中,我为
ttk.按钮创建了两个样式,每个样式都使用了
map
返回的版本。第二个版本抛出一个错误

至于“它应该如何工作?”,下面的例子也说明了这一点。基本上,这是一种为不同州的特定选项定制颜色的方法

import tkinter as tk
import tkinter.ttk as ttk
from dataclasses import dataclass, asdict
from collections import namedtuple

Theme_t = namedtuple('Theme_t', 'Base Primer Topcoat SubContrast Contrast Trim Hilight Accent Flat Gloss')
Theme = Theme_t('#bFbFbF', '#AFAFAF', '#C4C4C4', '#666666', '#888888', '#777777', '#444444', '#313131', '#2C2C2C', '#CCCCCC')
#YOURTHEME = Theme_t('#', '#', '#', '#', '#', '#', '#', '#', '#', '#')


@dataclass
class Button_dc:
    foreground:         str = Theme.Hilight
    background:         str = Theme.Topcoat 
    bordercolor:        str = Theme.Base 
    darkcolor:          str = Theme.Base
    lightcolor:         str = Theme.Base 
    highlightcolor:     str = Theme.Base
    relief:             str = 'flat'
    compound:           str = 'left'
    highlightthickness: int = 0
    shiftrelief:        int = 0
    width:              int = 0
    padding = [1,1,1,1] #l,t,r,b
    font:               str = "Consolas 12"
    anchor:             str = 'nswe'


class CustomTheme(ttk.Style):
    def __init__(self, basetheme='clam'):
        ttk.Style.__init__(self)
            
        self.theme_create('custom', basetheme, {
            'custom.TButton': { 
                #default 'normal' style
                'configure': asdict(Button_dc()),
                #style alterations for various button states
                'map': {
                    'background':  [('active', Theme.Primer), ('pressed', Theme.Topcoat)],
                    'foreground':  [('active', Theme.Hilight), ('pressed', Theme.Accent)],
                }
            },
            #this does not work
            #'cust.TButton': { 
            #    'configure': asdict(Button_dc()),
            #    'map': {
            #        'background':  ['active', Theme.Primer, 'pressed', Theme.Topcoat],
            #        'foreground':  ['active', Theme.Hilight, 'pressed', Theme.Accent],
            #    }
            #}
        })
        
        self.theme_use('custom')
        
        
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        CustomTheme()
        
        ttk.Button(self, text="Button 1", style='custom.TButton').grid()
        #ttk.Button(self, text="Button 2", style='cust.TButton').grid()


if "__main__" == __name__:
    app = App()
    app.title("Custom Theme Experiment And Example")
    app.geometry('800x600')
    app.mainloop()

我不能复制这个。当我按字面意思调用
x.map('Treeview')
两次时,一个接一个地调用,两个调用返回相同的值。无论我调用它多少次,我都会得到相同的值。您确定在两次调用
s.map
之间没有运行任何调用吗?@BryanOakley~我可以验证一下。我得到两个不同的结果,两个结果之间绝对没有通话。我甚至连续两次尝试这样调用它~
print(ttk.Style().map('Treeview'))
。我也得到了同样的结果。@BryanOakley是的,在两次通话之间什么都没有。如果这有什么不同的话,我会在Windows10上运行它。
import tkinter as tk
import tkinter.ttk as ttk
from dataclasses import dataclass, asdict
from collections import namedtuple

Theme_t = namedtuple('Theme_t', 'Base Primer Topcoat SubContrast Contrast Trim Hilight Accent Flat Gloss')
Theme = Theme_t('#bFbFbF', '#AFAFAF', '#C4C4C4', '#666666', '#888888', '#777777', '#444444', '#313131', '#2C2C2C', '#CCCCCC')
#YOURTHEME = Theme_t('#', '#', '#', '#', '#', '#', '#', '#', '#', '#')


@dataclass
class Button_dc:
    foreground:         str = Theme.Hilight
    background:         str = Theme.Topcoat 
    bordercolor:        str = Theme.Base 
    darkcolor:          str = Theme.Base
    lightcolor:         str = Theme.Base 
    highlightcolor:     str = Theme.Base
    relief:             str = 'flat'
    compound:           str = 'left'
    highlightthickness: int = 0
    shiftrelief:        int = 0
    width:              int = 0
    padding = [1,1,1,1] #l,t,r,b
    font:               str = "Consolas 12"
    anchor:             str = 'nswe'


class CustomTheme(ttk.Style):
    def __init__(self, basetheme='clam'):
        ttk.Style.__init__(self)
            
        self.theme_create('custom', basetheme, {
            'custom.TButton': { 
                #default 'normal' style
                'configure': asdict(Button_dc()),
                #style alterations for various button states
                'map': {
                    'background':  [('active', Theme.Primer), ('pressed', Theme.Topcoat)],
                    'foreground':  [('active', Theme.Hilight), ('pressed', Theme.Accent)],
                }
            },
            #this does not work
            #'cust.TButton': { 
            #    'configure': asdict(Button_dc()),
            #    'map': {
            #        'background':  ['active', Theme.Primer, 'pressed', Theme.Topcoat],
            #        'foreground':  ['active', Theme.Hilight, 'pressed', Theme.Accent],
            #    }
            #}
        })
        
        self.theme_use('custom')
        
        
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        CustomTheme()
        
        ttk.Button(self, text="Button 1", style='custom.TButton').grid()
        #ttk.Button(self, text="Button 2", style='cust.TButton').grid()


if "__main__" == __name__:
    app = App()
    app.title("Custom Theme Experiment And Example")
    app.geometry('800x600')
    app.mainloop()