在 tkinter 中更改滚动条的外观(使用 ttk 样式)

Posted

技术标签:

【中文标题】在 tkinter 中更改滚动条的外观(使用 ttk 样式)【英文标题】:Changing the appearance of a Scrollbar in tkinter (using ttk styles) 【发布时间】:2015-04-07 04:12:02 【问题描述】:

我想知道您是否可以帮助我解决 ttk 中的样式选项问题。我已经设法将大多数基本的 ttk 小部件更改为我喜欢的样式。我只停留在更改滚动条的样式。我已经搜索了几个小时寻找答案,不幸的是无济于事。

这是使用滚动条样式选项的示例代码:

import tkinter as tk                 
from tkinter import ttk

class Gui:
    def __init__(self,mainframe):

        #set the style
        style = ttk.Style()
        style.configure('Horizontal.TScrollbar',background = "blue" )   

        #Create a mainframe
        self.mainframe = mainframe
        self.mainframe.title("example")


        #creating scrollbar frame
        scrl_attr_frame = ttk.Frame(self.mainframe)                            
        scrl_attr_frame.grid(column=0,row=5,sticky="ns")                                           
        scrl_attr_frame.rowconfigure(0, weight=1)                                                   
        attr_canvas = tk.Canvas(scrl_attr_frame)                                                   
        h_scroll = ttk.Scrollbar(scrl_attr_frame,orient="horizontal", command=attr_canvas.xview)
        attr_canvas.configure(xscrollcommand=h_scroll.set)                                       
        attr_canvas.grid(column=0,row=0,sticky="ns")                                                                            
        h_scroll.grid(column=0, row=1,sticky="we") 
        attr_frame = ttk.Frame(attr_canvas)                                                        
        attr_frame.grid(column=0,row=0,sticky="ns")                                                 
        attr_canvas.create_window((0,0),window=attr_frame, anchor='nw')
        attr_frame.bind("<Configure>",lambda event, canvas=attr_canvas : canvas.configure(scrollregion=canvas.bbox("all"),width=200,height=200,takefocus=False,highlightthickness=0))#attribute_frame.winfo_height()/20,highlightthickness=0))

        #setup treeview widget
        tree_columns = ("c1", "c2", "c3")

        self.tree = ttk.Treeview(attr_frame,columns=tree_columns, show="headings",takefocus=False)
        self.tree.grid(column=0, row=0, sticky='nsew')

        for head in tree_columns:
            self.tree.heading(head,text=head,anchor="w")


root = tk.Tk()
myapp = Gui(root)
root.mainloop()

我还尝试了几种组合,包括:

style.configure('TScrollbar',background='blue') 

#and
style.configure('CustomScroll.Horizontal.TScrollbar',background='blue')

#in combination with
h_scroll = ttk.Scrollbar(scrl_attr_frame,orient="horizontal", command=attr_canvas.xview)
h_scroll['style'] = "CustomScroll.Horizontal.TScrollbar" 

非常感谢您的帮助!

【问题讨论】:

如果有人创建东西时也提供完整的文档和示例,那就太好了,否则什么都不做会更有效率。 什么平台?某些平台上的某些原生小部件无法更改。 @StephanL 我想你在 Mac 上,你甚至看不到水平滚动条...... 我正在使用 Windows 7。感谢您的宝贵时间! 太棒了!感谢您的时间和精力。无论结果如何,我都感谢您的帮助。 【参考方案1】:

看起来您只是想更改 Windows 主题下的水平滚动条的槽。 ttk 小部件由样式引擎提供的一组元素构成,并使用声明的布局进行组合。在 Windows 下,样式引擎是 Windows Visual Styles API,这意味着程序员无法控制用于绘制大多数常见元素的颜色或图像。按钮背景、滚动条槽和按钮以及滚动条拇指内部绘制的拇指甚至握把都是Windows提供的。

可以控制此以进行应用程序自定义,但代价是使您的应用程序在给定平台上看起来不再是标准的。为此,您必须提供自己的 UI 元素并定义新的小部件布局。最终,这可以转化为定义您自己的主题。 ttk 库中的 tcl 脚本提供了很好的示例,甚至还有一些完整的(如果旧的)主题使用位图在 ttk 的原始版本中声明基于图像的主题元素,称为 'tile'。

在这个特定的示例中,要获得具有自定义彩色背景的 Windows 水平滚动条,我们需要重新定义布局以使用来自 Tk 绘制元素的滚动条槽。在“默认”主题中使用的元素可以被复制并使用样式配置参数定义,然后由 Tk 自己绘制,而不是传递给第三方引擎。下面的代码生成一个像这样的滚动条,它使用 vsapi 样式引擎提供的标准按钮和拇指,但替换了槽。这个导入的槽理解troughcolor 样式配置选项,因此我们现在可以定义要使用的颜色。所有使用此样式的滚动条都将使用与小部件本身相同的颜色,不接受 troughcolor 选项。即:除非您为每种新颜色定义一种新样式,否则您不能让一个滚动条为蓝色而另一个为红色。

from tkinter import *
from tkinter.ttk import *

def main():
    app = Tk()
    style = Style()

    # import the 'trough' element from the 'default' engine.
    style.element_create("My.Horizontal.Scrollbar.trough", "from", "default")

    # Redefine the horizontal scrollbar layout to use the custom trough.
    # This one is appropriate for the 'vista' theme.
    style.layout("My.Horizontal.TScrollbar",
        [('My.Horizontal.Scrollbar.trough', 'children':
            [('Horizontal.Scrollbar.leftarrow', 'side': 'left', 'sticky': ''),
             ('Horizontal.Scrollbar.rightarrow', 'side': 'right', 'sticky': ''),
             ('Horizontal.Scrollbar.thumb', 'unit': '1', 'children':
                 [('Horizontal.Scrollbar.grip', 'sticky': '')],
            'sticky': 'nswe')],
        'sticky': 'we')])
    # Copy original style configuration and add our new custom configuration option.
    style.configure("My.Horizontal.TScrollbar", *style.configure("Horizontal.TScrollbar"))
    style.configure("My.Horizontal.TScrollbar", troughcolor="red")

    # Create and show a widget using the custom style
    hs = Scrollbar(app, orient="horizontal", style="My.Horizontal.TScrollbar")
    hs.place(x=5, y=5, width=150)
    hs.set(0.2,0.3)

    app.mainloop()

if __name__ == '__main__':
    main()

【讨论】:

【参考方案2】:

如果你使用clam 主题会更容易:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
style = ttk.Style()
style.theme_use('clam')

# list the options of the style
# (Argument should be an element of TScrollbar, eg. "thumb", "trough", ...)
print(style.element_options("Horizontal.TScrollbar.thumb"))

# configure the style
style.configure("Horizontal.TScrollbar", gripcount=0,
                background="Green", darkcolor="DarkGreen", lightcolor="LightGreen",
                troughcolor="gray", bordercolor="blue", arrowcolor="white")

hs = ttk.Scrollbar(root, orient="horizontal")
hs.place(x=5, y=5, width=150)
hs.set(0.2,0.3)

root.mainloop()

【讨论】:

【参考方案3】:

这在 Windows 上的 tkinter 中似乎是不可能的。 下面的答案是这样说的: ScrolledText Scrollbar Color (Python Tkinter)

滚动条文档:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/scrollbar.html 支持的样式字段:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Scrollbar.html

我尝试在我的 Windows 机器上同时传递“背景”和“槽色”均未成功。我还尝试将样式应用于一般滚动条: style.configure('TScrollbar', background="blue") 我的解决方案都不起作用。

另外一个论坛帖子也同意你不能在这里设置滚动条背景的样式: http://www.gossamer-threads.com/lists/python/python/822292

【讨论】:

以上是关于在 tkinter 中更改滚动条的外观(使用 ttk 样式)的主要内容,如果未能解决你的问题,请参考以下文章

Tkinter 如何正确设置组合框滚动条的样式

如何在 Tkinter 中获得带有滚动条的 Frame?

VC中怎么滚动条宽度怎么解决

tkinter:在画布上使用滚动条

Python,Tkinter:如何在可滚动画布上获取坐标

Tkinter 之ProgressBar进度条标签