【问题标题】:Changing shapes of tkinter scale widgets更改 tkinter 比例小部件的形状
【发布时间】:2020-08-06 14:54:27
【问题描述】:

我想更改 tkinter 缩放小部件的形状。基本上我想将滑块和槽都更改为不同的形状。有谁知道如何做到这一点?我在网上查了一下,没有找到我的查询的任何结果。作为 tkinter 的新手,请尽量保持简单。我发现了一些关于更改按钮小部件形状的结果(look here),但这似乎对我没有多大帮助。我希望我的体重秤看起来像这张图片顶部显示的体重秤:

秤不必与上图中的完全一样。任何关于如何让我的体重秤看起来更好的建议将不胜感激。

这是我的代码的相关部分:

scale1 = ttk.Scale(root,from_=100,to=0,orient=VERTICAL,variable=s_var1)
scale2 = ttk.Scale(root,from_=100,to=0,orient=VERTICAL,variable=s_var2)
scale3 = ttk.Scale(root,from_=100,to=0,orient=VERTICAL,variable=s_var3)
scale4 = ttk.Scale(root,from_=100,to=0,orient=VERTICAL,variable=s_var4)
scale5 = ttk.Scale(root,from_=100,to=0,orient=VERTICAL,variable=s_var5)
#displaying the scale widgets on the screen
scale1.grid(row=0,column=0,padx=40,pady=10)
scale2.grid(row=0,column=1,padx=40,pady=10)
scale3.grid(row=0,column=2,padx=40,pady=10)
scale4.grid(row=0,column=3,padx=40,pady=10)
scale5.grid(row=0,column=4,padx=40,pady=10)
#disabling the scales
scale1.config(state=DISABLED)
scale2.config(state=DISABLED)
scale3.config(state=DISABLED)
scale4.config(state=DISABLED)
scale5.config(state=DISABLED)

我也使用过 tkinter.ttk 模块,但我也不喜欢它的小部件。

【问题讨论】:

    标签: python python-3.x tkinter widget scale


    【解决方案1】:

    从图片中,我假设您想要显示一些数量,而不是使用比例来选择值。在这种情况下,我宁愿使用Progressbar 而不是Scale。这将为您提供与图片顶部相似但具有简单矩形形状的内容:

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    style = ttk.Style(root)
    
    # configure Progressbar style to be flat and with the colors from the pictures
    style.configure('my.Vertical.TProgressbar', background='#f7f4bf', troughcolor='#8a7852',
                    pbarrelief='flat', troughrelief='flat')
    
    pbar1 = ttk.Progressbar(root, maximum=100, value=25, orient='vertical', style='my.Vertical.TProgressbar')
    pbar2 = ttk.Progressbar(root, maximum=100, value=74, orient='vertical', style='my.Vertical.TProgressbar')
    pbar3 = ttk.Progressbar(root, maximum=100, value=10, orient='vertical', style='my.Vertical.TProgressbar')
    pbar4 = ttk.Progressbar(root, maximum=100, value=45, orient='vertical', style='my.Vertical.TProgressbar')
    pbar5 = ttk.Progressbar(root, maximum=100, value=50, orient='vertical', style='my.Vertical.TProgressbar')
    
    pbar1.grid(row=0, column=0, padx=40, pady=10)
    pbar2.grid(row=0, column=1, padx=40, pady=10)
    pbar3.grid(row=0, column=2, padx=40, pady=10)
    pbar4.grid(row=0, column=3, padx=40, pady=10)
    pbar5.grid(row=0, column=4, padx=40, pady=10)
    
    root.configure(bg="#231303")
    root.mainloop()
    

    您可以使用pbar1.configure(value=<new_value>)更改进度条显示的值。

    但是,我不知道如何更改进度条的形状。要获得条的自定义形状,可以从 Canvas 创建自定义条类并使用 PIL 获得透明形状。

    import tkinter as tk
    from tkinter import ttk
    
    from PIL import Image, ImageTk
    
    root = tk.Tk()
    style = ttk.Style(root)
    
    
    class MyBar(tk.Canvas):
        def __init__(self, master, shape, value=0, maximum=100,
                     bg="#231303", trough_color='#8a7852', bar_color='#f7f4bf'):
            # open shape mask with PIL
            im_shape_alpha = Image.open(shape).convert('L')
            # create bar shape image with the choosen backgroound color
            im_shape = Image.new('RGBA', im_shape_alpha.size, bg)
            # apply shape as alpha mask to "cut out" the bar shape
            im_shape.putalpha(im_shape_alpha)
            width, height = im_shape_alpha.size
            # create the canvas
            tk.Canvas.__init__(self, master, bg=trough_color, width=width, height=height, highlightthickness=0)
    
            self._value = value  # bar value
            self.maximum = maximum  # maximum value
    
            # bar width and height
            self.height = height
            self.width = width
            
            # create tkinter image for the shape from the PIL Image
            self.img_trough = ImageTk.PhotoImage(im_shape, master=self)
            # create bar to display the value
            self.create_rectangle(0, height, width, height * (1 - value/self.maximum), width=0, fill=bar_color, tags='pbar')
            # display shape on top
            self.create_image(0, 0, anchor='nw', image=self.img_trough)
    
        @property
        def value(self):
            """Return bar's value'"""
            return self._value
    
        @value.setter
        def value(self, value):
            """Set bar's value'"""
            self._value = value
            # adjust bar height to value
            self.coords('pbar', 0, self.height, self.width, self.height*(1 - value/self.maximum))
    
    shape = '/path/to/shape/picture'
    
    bar1 = MyBar(root, shape)
    bar2 = MyBar(root, shape)
    bar3 = MyBar(root, shape)
    bar4 = MyBar(root, shape)
    bar5 = MyBar(root, shape=shape, value=60, bg='navy', trough_color='sky blue', bar_color='royal blue')
    
    bar1.pack(side='left', padx=10, pady=40)
    bar2.pack(side='left', padx=10, pady=40)
    bar3.pack(side='left', padx=10, pady=40)
    bar4.pack(side='left', padx=10, pady=40)
    bar5.pack(side='left', padx=10, pady=40)
    
    bar2.value = 75
    bar3.value = 50
    bar4.value = 100
    root.mainloop()
    

    结果:

    在本例中用于shape 的图像:

    在上面的代码中,shape 是一张黑白图片,用作 alpha 蒙版。这个想法是,条形图是在 Canvas 上绘制的 bar_color 矩形,背景为 trough_color。然后在这个栏的顶部我放了一个颜色为bg的图像,除了形状部分是透明的并且已经从背景中切掉(shape图片的黑色部分)。

    【讨论】:

    • 感谢它非常有帮助并解决了我的问题。我实际上对 tkinter 很陌生,所以我不知道进度条。
    • @Jovan 不客气。我在答案中添加了一种获得形状条的方法。它比仅使用 Progressbar 更复杂,但我已将 cmets 放入代码中以尝试解释。
    • 非常感谢您不厌其烦。我开始认为我必须坚持 tkinter 缩放小部件的无聊默认样式。是的,我明白你做了什么。再次感谢。
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    相关资源
    最近更新 更多