是否可以在 tkinter 中创建切换按钮?
Is it posible to create toggle switch button in tkinter?
我想做一个切换按钮来改变GUI中的主题,不知道是否可以实现类似于下图的东西?
除了使用像这样的“缩放”小部件之外,还有更好的方法吗?
from tkinter import *
window = Tk()
s1 = Scale(window, from_=0, to=1, orient=HORIZONTAL)
s1.pack()
mainloop()
您可以使用 Canvas
创建自定义小部件形状。如果您想重用它,您可能想通过继承 Canvas
class 来创建一个单独的 class。
我创建了一个类似的拨动开关。您可以进一步改进。 (注意:您不能使用我创建的 class 的图像,但您可以更改颜色)
from tkinter import *
class ToggleButton(Canvas):
def __init__(self, root, command=None, fg='black', bg='gray', *args, **kwargs):
super().__init__(*args, **kwargs)
self.configure(width=100, height=50, borderwidth=0, highlightthickness=0)
self.root = root
self.back_ground = self.create_arc((0, 0, 0, 0), start=90, extent=180, fill=bg, outline='')
self.back_ground1 = self.create_arc((0, 0, 0, 0), start=-90, extent=180, fill=bg, outline='')
self.rect = self.create_rectangle(0, 0, 0, 0, fill=bg, outline='')
self.btn = self.create_oval(0, 0, 0, 0, fill=fg, outline='')
self.bind('<Configure>', self._resize)
self.bind('<Button>', self._animate, add='+')
self.bind('<Button>', command, add='+')
self.state = 0
def _resize(self, event):
self.coords(self.back_ground, 5, 5, event.height-5, event.height-5)
self.coords(self.back_ground1, 5, 5, event.height, event.height-5)
factor = event.width-(self.coords(self.back_ground1)[2]-self.coords(self.back_ground1)[0])-10
self.move(self.back_ground1, factor, 0)
self.coords(self.rect, self.bbox(self.back_ground)[2]-2, 5, self.bbox(self.back_ground1)[0]+2, event.height-5)
self.coords(self.btn, 5, 5, event.height-5, event.height-5)
if self.state:
self.moveto(self.btn, self.coords(self.back_ground1)[0]+4, 4)
def _animate(self, event):
x, y, w, h = self.coords(self.btn)
x = int(x-1)
y = int(y-1)
if x == self.coords(self.back_ground1)[0]+4:
self.moveto(self.btn, 4, 4)
self.state = 0
else:
self.moveto(self.btn, self.coords(self.back_ground1)[0]+4, 4)
self.state = 1
def get_state(self):
return self.state
#Your own function
def hello(event='Nooo'):
print(event)
if bool(btn.get_state()):
print('State is 1')
elif not bool(btn.get_state()):
print('State is 0')
root = Tk()
btn = ToggleButton(root, lambda _:hello('Hello'), 'red', 'green')
btn.pack()
btn2 = ToggleButton(root, command=hello)
btn2.pack(expand=True, fill='both')
Button(root, text='Text').pack(expand=True, fill='both')
root.mainloop()
使用方法:
- 使用此小部件就像使用任何其他小部件一样。
- 要获取开关的状态,您可以使用
get_state()
方法
- 当椭圆在右边时开关的状态为1,当椭圆在左边时开关的状态为0。
*(注意:您仍然可以使用 Canvas
小部件的方法。如果您不需要它们,请重写这些方法并提供 pass
)
FWIW,JacksonPro 的回答很好,尽管有一个差一错误——在 _animate
函数中,它应该是
if x == self.coords(self.back_ground1)[0]+3:
self.moveto(self.btn, 4, 4)
self.state = 0
谢谢!
我想做一个切换按钮来改变GUI中的主题,不知道是否可以实现类似于下图的东西?
除了使用像这样的“缩放”小部件之外,还有更好的方法吗?
from tkinter import *
window = Tk()
s1 = Scale(window, from_=0, to=1, orient=HORIZONTAL)
s1.pack()
mainloop()
您可以使用 Canvas
创建自定义小部件形状。如果您想重用它,您可能想通过继承 Canvas
class 来创建一个单独的 class。
我创建了一个类似的拨动开关。您可以进一步改进。 (注意:您不能使用我创建的 class 的图像,但您可以更改颜色)
from tkinter import *
class ToggleButton(Canvas):
def __init__(self, root, command=None, fg='black', bg='gray', *args, **kwargs):
super().__init__(*args, **kwargs)
self.configure(width=100, height=50, borderwidth=0, highlightthickness=0)
self.root = root
self.back_ground = self.create_arc((0, 0, 0, 0), start=90, extent=180, fill=bg, outline='')
self.back_ground1 = self.create_arc((0, 0, 0, 0), start=-90, extent=180, fill=bg, outline='')
self.rect = self.create_rectangle(0, 0, 0, 0, fill=bg, outline='')
self.btn = self.create_oval(0, 0, 0, 0, fill=fg, outline='')
self.bind('<Configure>', self._resize)
self.bind('<Button>', self._animate, add='+')
self.bind('<Button>', command, add='+')
self.state = 0
def _resize(self, event):
self.coords(self.back_ground, 5, 5, event.height-5, event.height-5)
self.coords(self.back_ground1, 5, 5, event.height, event.height-5)
factor = event.width-(self.coords(self.back_ground1)[2]-self.coords(self.back_ground1)[0])-10
self.move(self.back_ground1, factor, 0)
self.coords(self.rect, self.bbox(self.back_ground)[2]-2, 5, self.bbox(self.back_ground1)[0]+2, event.height-5)
self.coords(self.btn, 5, 5, event.height-5, event.height-5)
if self.state:
self.moveto(self.btn, self.coords(self.back_ground1)[0]+4, 4)
def _animate(self, event):
x, y, w, h = self.coords(self.btn)
x = int(x-1)
y = int(y-1)
if x == self.coords(self.back_ground1)[0]+4:
self.moveto(self.btn, 4, 4)
self.state = 0
else:
self.moveto(self.btn, self.coords(self.back_ground1)[0]+4, 4)
self.state = 1
def get_state(self):
return self.state
#Your own function
def hello(event='Nooo'):
print(event)
if bool(btn.get_state()):
print('State is 1')
elif not bool(btn.get_state()):
print('State is 0')
root = Tk()
btn = ToggleButton(root, lambda _:hello('Hello'), 'red', 'green')
btn.pack()
btn2 = ToggleButton(root, command=hello)
btn2.pack(expand=True, fill='both')
Button(root, text='Text').pack(expand=True, fill='both')
root.mainloop()
使用方法:
- 使用此小部件就像使用任何其他小部件一样。
- 要获取开关的状态,您可以使用
get_state()
方法 - 当椭圆在右边时开关的状态为1,当椭圆在左边时开关的状态为0。
*(注意:您仍然可以使用 Canvas
小部件的方法。如果您不需要它们,请重写这些方法并提供 pass
)
FWIW,JacksonPro 的回答很好,尽管有一个差一错误——在 _animate
函数中,它应该是
if x == self.coords(self.back_ground1)[0]+3:
self.moveto(self.btn, 4, 4)
self.state = 0
谢谢!