强制 TkInter Scale 滑块对齐鼠标 [英] Force TkInter Scale slider to snap to mouse

查看:24
本文介绍了强制 TkInter Scale 滑块对齐鼠标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个 GUI 有一个 TkInter Scale 并且他们点击比例尺上的某个地方时,默认行为似乎是沿着朝向鼠标的方向沿着 Scale 滑动滑块(然后意外地超过它们的鼠标).

When a GUI has a TkInter Scale and they click somewhere on the scale, the default behavior seems to be to slide the slider along the Scale in the direction towards the mouse (and then unexpectedly past their mouse).

相反,我想要的是让滑块在用户点击滑块上的任意位置时始终跳转到并保持连接到用户的鼠标点.如果他们点击比例尺上的特定点,滑块应直接跳到该点.

What I'd want instead is to have the slider always jump to and stay attached to the user's mouse point while they're clicking anywhere on the slider. If they click to a particular point on the Scale, the slider should jump directly to that point.

我在下面有一些代码尝试执行此操作,但似乎不起作用,我找不到原因.

I have some code below which attempts to do this but doesn't seem to work and I cannot find the reason for it.

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.这个想法是在用户在秤上按下鼠标按钮时调用它.然后,它尝试根据事件像素位置和比例大小计算点击比例的分数位置,将其转​​换为比例值,并将其设置为用户点击的那个值.但是,我发现滑块并不总是跳到同一个地方,即使它报告它已设置为我期望的值.怎么回事?

The pertinent function here is scaleFunc1. The idea is to have this called whenever the user presses their mouse button on the scale. It then tries to calculate, from the event pixel location and the Scale size, the fractional position of the click on the scale, convert this to a scale value, and set it to that value where the user clicked. However, I'm finding that the slider doesn't always jump to the same place, even if it reports it was set to the value I'd expect. What's going on?

我怀疑这与用户按住鼠标按钮的几分之一秒内仍试图移动的幻灯片有关.

I suspect it has something to do with the slide still trying to move for the fraction of a second the user keeps the mouse button pressed down.

推荐答案

这实际上是默认的右键单击行为.如果您也想让左键单击这样做,那么最简单的方法就是简单地检测左键单击并告诉 tkinter 它是右键单击:

That's actually the default right-click behavior. If you want to make the left click do that too, then the easiest thing is to simply detect leftclick and tell tkinter it was a right click instead:

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()

这篇关于强制 TkInter Scale 滑块对齐鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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