当GUI有一个TkInter Scale
并且它们点击比例尺上的某个位置时,默认行为似乎是沿着Scale向滑动方向滑动滑块(然后意外地超过鼠标)。
我想要的是让滑块始终跳转并保持与用户鼠标点的连接,同时他们点击滑块上的任意位置。如果他们单击“比例”上的特定点,滑块应直接跳到该点。
我在下面有一些代码试图这样做,但似乎没有用,我找不到它的原因。
import tkinter as tk
from tkinter import ttk
def show_values():
print('w1 set to',w1.get())
def snapToVal1(val):
scaleVal = float(w1.get())
if int(scaleVal) != scaleVal:
w1.set(round(float(val)))
def scaleFunc1(event):
g = w1.grid_info()
w1.set(round(8 * (event.y - g['pady'])/(w1.winfo_height() - 2*g['pady'] - 2*g['ipady']))-1)
print('w1 set to',w1.get())
#---
root = tk.Tk()
f1 = ttk.Frame(root, relief = tk.GROOVE)
ttk.Label(f1, text='Stellar\nType').grid(row=0,column=0, columnspan=2,padx=2,pady=2)
for i,text in enumerate(['O','B','A','F','G','K','M','L']):
ttk.Label(f1, text = text).grid(row=i+1,column=0,pady=5,padx=(2,0))
w1 = ttk.Scale(f1, to=7, command=snapToVal1, orient=tk.VERTICAL)
w1.grid(row = 1, column = 1, rowspan = 8, pady=5, padx=2, sticky='nsew')
w1.bind('<Button-1>',scaleFunc1)
f1.grid(row = 0, column = 0,padx=(2,1),pady=2,sticky='nsew')
ttk.Button(root, text='Show', command=show_values).grid(row=1,column=0)
root.mainloop()
这里的相关功能是scaleFunc1
。这个想法是每当用户在秤上按下鼠标按钮时调用它。然后,它尝试从事件像素位置和比例大小计算比例上点击的分数位置,将其转换为比例值,并将其设置为用户单击的值。但是,我发现滑块并不总是跳到同一个地方,即使它报告它被设置为我期望的值。发生了什么事?
我怀疑它与幻灯片有关,仍然试图移动一小段时间用户按住鼠标按钮。
答案 0 :(得分:5)
这实际上是默认的右键单击行为。如果你想让左键单击也这样做,那么最简单的方法是简单地检测leftclick并告诉tkinter它是一个右键单击:
import tkinter as tk
from tkinter import ttk
class Scale(ttk.Scale):
"""a type of Scale where the left click is hijacked to work like a right click"""
def __init__(self, master=None, **kwargs):
ttk.Scale.__init__(self, master, **kwargs)
self.bind('<Button-1>', self.set_value)
def set_value(self, event):
self.event_generate('<Button-3>', x=event.x, y=event.y)
return 'break'
def show_values():
print('w1 set to',w1.get())
root = tk.Tk()
f1 = ttk.Frame(root, relief = tk.GROOVE)
ttk.Label(f1, text='Stellar\nType').grid(row=0,column=0, columnspan=2,padx=2,pady=2)
for i,text in enumerate(['O','B','A','F','G','K','M','L']):
ttk.Label(f1, text = text).grid(row=i+1,column=0,pady=5,padx=(2,0))
w1 = Scale(f1, to=7, orient=tk.VERTICAL)
w1.grid(row = 1, column = 1, rowspan = 8, pady=5, padx=2, sticky='nsew')
f1.grid(row = 0, column = 0,padx=(2,1),pady=2,sticky='nsew')
ttk.Button(root, text='Show', command=show_values).grid(row=1,column=0)
root.mainloop()