Python Tkinter滑块自定义 [英] Python Tkinter slider customization

查看:188
本文介绍了Python Tkinter滑块自定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是tkinter的新手,我想创建一个类似于此图片中的滑块:

I'm new with tkinter, and I want to create a slider like the one in this picture:

但是我不知道这是否有可能,所以我的问题是:这有可能吗,有人对我有快速的教学指导吗?

But I have no idea if this is even possible, so my question is: Is this possible, and does someone has a quick tutorial or something for me?

推荐答案

这可以通过自定义ttk主题来完成.想法是将图像用于刻度的槽(垂直线)和滑块(圆形).可以使用以下图像从这些图像创建主题元素:

This can be done by customizing a ttk theme. The idea is to use images for the scale's trough (a vertical line) and slider (a circle). Theme elements can be created from these images using:

style.element_create('custom.Vertical.Scale.trough', 'image', img_trough)
style.element_create('custom.Vertical.Scale.slider', 'image', img_slider)

然后必须使用以下方式创建秤的布局

Then the layout of the scale has to be created with

style.layout('custom.Vertical.TScale',
             [('custom.Vertical.Scale.trough', {'sticky': 'ns'}),
              ('custom.Vertical.Scale.slider',
               {'side': 'top', 'sticky': '',
                'children': [('custom.Vertical.Scale.label', {'sticky': ''})]
                })])

,以便它使用创建的元素.我添加了一个标签来显示值,但只能通过样式访问它,因此我们必须为每个创建的比例使用唯一的样式名称,例如'<scale name>.custom.Vertical.TScale'.然后我们可以使用

so that it uses the created elements. I have added a label to display the value but it will be accessible only through the style so we have to use a unique style name for each created scale, e.g. '<scale name>.custom.Vertical.TScale'. Then we can change the text with

style.configure('<scale name>.custom.Vertical.TScale', text=<value>)

要使标签的文本与秤的值保持最新,我们可以在秤的变量上使用迹线,如下面的CustomScale类所示.

To keep the label's text up to date with the scale's value, we can use a trace on the scale's variable, as done in the CustomScale class below.

这是完整的代码:

import tkinter as tk
from tkinter import ttk

class CustomScale(ttk.Scale):
    def __init__(self, master=None, **kw):
        self.variable = kw.pop('variable', tk.DoubleVar(master))
        ttk.Scale.__init__(self, master, orient='vertical', variable=self.variable, **kw)
        self._style_name = '{}.custom.Vertical.TScale'.format(self) # unique style name to handle the text
        self['style'] = self._style_name
        self.variable.trace_add('write', self._update_text)
        self._update_text()

    def _update_text(self, *args):
        style.configure(self._style_name, text="{:.1f}".format(self.variable.get()))

trough = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x02\x00\x00\x00\x90\x08\x06\x00\x00\x00"\x18\xbal\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x00\tpHYs\x00\x00\n\xfc\x00\x00\n\xfc\x01\x99\xdb\xbb\xef\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x00\x1fIDAT8\x8dc\\\xb5j\xd5\x7f\x06\x06\x06\x06&\x06(\x18e\x8c2F\x19\xa3\x8c\x91\xc9\x00\x00\xf7\xe7\x04\x1dd\xcc\xbe\x83\x00\x00\x00\x00IEND\xaeB`\x82'
slider = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x00\tpHYs\x00\x00\x1d\x87\x00\x00\x1d\x87\x01\x8f\xe5\xf1e\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x05\xa4IDATh\x81\xd5\x9a\xcfo\x1bE\x14\xc7?3\xcez\x13\xb7k7\xb1\x9c4\x07\xdaT \xe8\x11*\x0e\xe5\x04A\xaa\x80\x1cP\x13\xe2\xcd\x85\x1eB\xab\x1e\x81\x0b\xe2ohOpD\xa8p(\x95\xaa\x8d\xa0\xad\x04F\xfc\x90\xc2\xad\x1c\xa0\xaa8\x15\xd1\xaa\xa4\x97\xd6?b\xe2\x9f\xb1\xb3\xf6>\x0e\xf6\x86%q\x9a8mj\xf7s\xb2gv\xc7\xdf7\x9e\x9d7\xef\xbdU<\x06\x16\x17\x17\x07\xd2\xe9\xf4\xcb\xa1P\xe8\xb8\xe7yG\x95R\xcf\x01\x07\x80X\xfb\x92\x02\xb0""\xb7\xb5\xd6\xb7\x94R\xd7\xe3\xf1\xf8\xef\x93\x93\x93\x8dG\xfdm\xf5(\xa2s\xb9\xdc\x9b\xc0)\x11y\x0b\xb0\xba\x1c\xa2(")\xa5\xd4W\x89D\xe2\x87\xdd\x1a\xd3\xb5\x01\x8e\xe3\x0c\x01\xa7\x81\x8f\x80C~\xbba\x18\x0c\r\ra\x9a&\x86a\x10\n\x85\xd0Z\x03\xe0y\x1e\xcdf\x13\xd7u\xa9\xd7\xeb\xd4j5\xd6\xd6\xd6\x82\xc3\xde\x13\x91\xf3\xd5j\xf5\xc2\xfc\xfc|m\xcf\x0cXXX\x98\x11\x91O\x80g|\xd1\xd1h\x14\xcb\xb2\x18\x18\x18\xe8f(\x1a\x8d\x06\xa5R\x89b\xb1\x88\xeb\xba~\xf3\x92R\xea\x83d2ym\xa7\xe3\xec\xc8\x80K\x97.\r\x1b\x86q\x01\x98\x060M\x93\x91\x91\x11\xf6\xed\xdb\xd7\x95\xe8N\x88\x08\xd5j\x95|>O\xbd^\xf7\x9b\xbf6\x0c\xe3\xcc\xf4\xf4\xf4\xcav\xf7ok\xc0\xe5\xcb\x97\x8fi\xad\xbf\x01\x0ek\xad\x89\xc7\xe3D\xa3Q\x94\xda\xf5\xe3\xb3%\x85B\x81\xe5\xe5e<\xcf\x03\xb8\x0b\xcc\xd8\xb6}\xf3a\xf7<T\xc5\xc2\xc2\xc2k"r\r\x88\x9a\xa6\xc9\xf8\xf8x\xd7K\xa5[\x1a\x8d\x06\x0f\x1e<\xa0V\xab\x01\x94\x95R\xef$\x93\xc9\x1f\xb7\xba~K\x03\x1c\xc7y\x1dH\x01\xa6eY\x8c\x8e\x8e\xee\xc9\xacwBD\xc8d2\x94J%\x80\x9a\x88L\xcd\xcd\xcd-v\xba\xb6\xa3\xa2\xf6\xb2\xf9\x05\xb0b\xb1\x18\x89Db\xef\xd4n\x81\x88\x90\xcb\xe5(\x14\n\x00E\xe0\xd5N\xcbi\x93\x01W\xae\\9\xe0\xba\xee\r\xe0\xc8\x93\x9e\xf9Nd2\x19\x8a\xc5"\xc0=\xe0%\xdb\xb6\xf3\xc1~\xbd\xf1\x06\xd7u\xbf\x00\x8e\x98\xa6\xd9s\xf1\x00\x89D\x82\xc1\xc1Ah\xf9\x9c\xcf6\xf6\xff\xcf\x00\xc7q\xa6\x81i\xad5\xe3\xe3\xe3=\x17\x0f\xa0\x94bll\xccw\x8a\xb3\x8e\xe3\xbc\x1d\xec_7\xa0\xeda?\x01\x88\xc7\xe3{\xbe\xdbt\x83a\x18\xc4\xe3q\xff\xeb\xa7\xa9T\xca\xf4\xbf\x04\xff\x81\xd3\xc0!\xd34\x89F\xa3OR\xdf\x8e\x88\xc5b\x98\xa6\t0Q.\x97\xdf\xf3\xdb5\xb4\x0ef\xb4\xce6\x0c\x0f\x0f\xf7\xc5\xd2\xe9\xc4\xc8\xc8\x88\xff\xf1\xe3\xb6\xe6\x96\x01\xd9l\xf6\r\xe0\x90a\x18\xec\xdf\xbf\xbfG\xf2\xb6\'\x12\x89\x10\x0e\x87\x01\x0e\xe7r\xb9\x13\xf0\xdf\x12:\x05\xf4\xe5\xd2\t\xa2\x94\nN\xf0)\x00\xb5\xb8\xb88\x90\xcdf\x97\x81\xe8\xc4\xc4D_=\xbc\x9dp]\x97\xa5\xa5%h\x05Iq\x9dN\xa7_\x06\xa2\x86a\xf4\xbdxh\xedH\x86a\x00\xc4<\xcf;\xa6C\xa1\xd0q\x80\xa1\xa1\xa1\xde*\xeb\x82H$\x02\x80R\xea\x15\xedy\xdeQ\xc0\xdf\xa2\x9e\n\xda\xff\x00\xc0\x0b\xba\x1d\x80\x07\x1b\xfb\x9e\xf6N\x84R\xeay\r\x0c\x03\x84B\xa1^j\xea\x8a\x80\xd6\x03\x1a\xd8\x0f\xf4\xad\xf3\xeaD@\xab\xb5\xe94\xfa\xb4\xa1\x812\xb4\x02\x88\xa7\x85\x80\xd6\x92\x06\xfe\x01h6\x9b=\x13\xd4-\x01\xad\xffh\x11\xb9\r\x04s3}\x8f\xafUD\xfe\xd2Z\xeb[@0\'\xd3\xf7\x04\xb4\xfe\xa9\x9b\xcd\xe6\xaf\x00\xab\xab\xab\xbdS\xd4%\xbeV\x11\xb9\xae\xc7\xc6\xc6~\x03\n\xae\xeb\xd2h<r\xb2x\xcfi4\x1a\xfe\x12Z\xd1Z\xdf\xd0\x93\x93\x93\r\x11\xf9\x1e\xf0\xf30}M@c\xca\xb6\xed\xa6\xef\x07.\x02~\xfa\xa2o\x11\x91\xa0\x01\x17\xa1\x1d\xd0\x8c\x8e\x8e\xfe\x08\xdcs]\x97J\xa5\xd2#y\xdbS\xa9T\xfc\xb4\xfc\xdf\x89D\xe2gh\x1b\xd0^F\xe7\x01\xf2\xf9\xfc\xd6#\xf4\x18_\x9b\x88\x9c\xf3\x0b"\xebG\x89j\xb5z\x01X\xaa\xd7\xeb~:\xaf\xafXYY\xf1g\xff\xaeeY_\xfa\xed\xeb\x06\xcc\xcf\xcf\xd7D\xe4C\x80\xe5\xe5\xe5\xberl\x8dFc}\xf6\x95R\xefOMM\xad;\x82\xff\x1d\xe6\xe6\xe6\xe6\xae\x02_{\x9eG:\x9d\xee\x8b\xf3\x91\x88p\xff\xfe}<\xcfC)\xe5$\x93\xc9o\x83\xfd\x9bN\xa3\x86a\x9c\x01\xee\xd6j\xb5\xbe0"\x93\xc9\xf8\x9e\xf7\x8e\x88\x9c\xdd\xd8\xbf\xc9\x80vYg\x06(\x96\xcber\xb9\\O\x8c\x10\x11\xb2\xd9\xac\xbfm\x16\xb4\xd63\xb6moz8;\xc6\x03\xb6m\xdf\x14\x91\x93@\xadP(\x90\xc9d\x9e\xa8\x11"B:\x9d\xf67\x93\x9aR\xea\xe4\xec\xec\xec\x1f\x9d\xae\xddI\x89\xe9*\x103M\x93\x83\x07\x0f\xeey\xec\xbc\xb1\xc4D\xabN\xf6\xd3V\xd7o\x1bG:\x8e\xf3"\xf0\rp\xc4/\xf2\xc5b\xb1\xedn\xdb\x15\x1b\x8a|w\xb4\xd63[\xcd\xbc\xcf\x8e\x02\xe1v\xd5\xe6s`\x16\xfe+\xb3F"\x91G\x8e\xa5E\x84J\xa5B>\x9f_/~+\xa5\x1c\x119\xdbi\xcdo\xa4\xab_o\x17\x17>\x05&\xa0\x95\xde\xb0,kW\x85n\xd7u)\x97\xcb\x94J\xa5`\xd5\xfe\xaeR\xea\xfd\x8d[\xe5\xc3\xe8z\xfaR\xa9\x94\xd9\xce\xcf\x7f\x0c\x1c\xf6\xdb\xc3\xe10\x83\x83\x83\x84\xc3a\xc2\xe1\xf0\xfa\xab\x06"\x82\x88\xac\x1f\x83\xd7\xd6\xd6X]]\xdd\xe8(\xff\x16\x91s\x96e}\x19tR{b\x80O\xfbe\x8f\x13"\xf2.0E\xeb\xed\x94nX\x11\x91\xef\x94R_\x01?\xd9\xb6\xbd\xab\xa0\xfc\xb1$\x83\x1c\xc7\ty\x9ewL)\xf5\x8aR\xea(\xf0,\x10\x07\xfc|}\x11X\xa6\xe5\x8cn\x89\xc8u\xad\xf5\x8d\xdd\x8a\x0e\xf2/#\xf8\x81 \xf2;_\x08\x00\x00\x00\x00IEND\xaeB`\x82'

root = tk.Tk()
# create images used for the theme
img_trough = tk.PhotoImage(master=root, data=trough)
img_slider = tk.PhotoImage(master=root, data=slider)
style = ttk.Style(root)
# create scale elements
style.element_create('custom.Vertical.Scale.trough', 'image', img_trough)
style.element_create('custom.Vertical.Scale.slider', 'image', img_slider)
# create custom layout
style.layout('custom.Vertical.TScale',
             [('custom.Vertical.Scale.trough', {'sticky': 'ns'}),
              ('custom.Vertical.Scale.slider',
               {'side': 'top', 'sticky': '',
                'children': [('custom.Vertical.Scale.label', {'sticky': ''})]
                })])

scale1 = CustomScale(root, from_=0, to=10)
scale1.pack(side='left')
scale2 = CustomScale(root, from_=0, to=100)
scale2.pack(side='left')
root.mainloop()

主要缺点是,如果单击标签,幻灯片将不起作用.

The main drawback is that the slide does not react if you click on the label.

注意:要使水平比例尺具有相同的效果,请在所有样式元素中将垂直"替换为水平",将水平线用于槽并将布局更改为:

Note: to have the same for a horizontal scale, replace the 'Vertical' by 'Horizontal' in all style elements, use a horizontal line for the trough and change the layout into:

style.layout('custom.Horizontal.TScale',
             [('custom.Horizontal.Scale.trough', {'sticky': 'ew'}),
              ('custom.Horizontal.Scale.slider',
               {'side': 'left', 'sticky': '',
                'children': [('custom.Horizontal.Scale.label', {'sticky': ''})]
                })])

这篇关于Python Tkinter滑块自定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆