Tkinter - 每 X 秒采样一次比例值?

问题描述 投票:0回答:1

所以我有一个带有比例滑块的基本 tkinter GUI。 我想使用计时器每 1 秒采样一次刻度值(应该模拟汽车加速器)

如何在我的代码中添加计时器?

import tkinter as tk
import ttkbootstrap as ttk

SCALE_VALUE_MIN = -20
SCALE_VALUE_MAX = 100
SCALE_VALUE_DEFAULT = 0

MAX_FORWARD_ACC = 3 # m/s^2
MAX_BACKWARD_ACC = MAX_FORWARD_ACC / 3

MAX_FORWARD_SPEED = 220 / 3.6 # 220 km/h to m/s
MAX_BACKWARD_SPEED = 20 / 3.6 # 20 km/h to m/s

def scaleupdate(value):
    output_str.set(value)

def scalerelease(value):
    scale.set(SCALE_VALUE_DEFAULT)

window = ttk.Window(themename= 'journal')
window.title('Demo')
window.geometry('300x150')

# frame
frame1 = ttk.Frame(master = window)

# min_label
min_label = ttk.Label(master = frame1, text = str(SCALE_VALUE_MIN))
min_label.pack(side = 'left', padx = 10)

# scale
scalevar = tk.DoubleVar()
scale = ttk.Scale(master = frame1, variable = scalevar, from_= SCALE_VALUE_MIN, to = SCALE_VALUE_MAX, orient = 'horizontal', command = scaleupdate)
scale.set(SCALE_VALUE_DEFAULT)
scale.bind('<ButtonRelease-1>', scalerelease)
scale.pack(side = 'left', padx = 10)

# max_label
max_label = ttk.Label(master = frame1, text = str(SCALE_VALUE_MAX))
max_label.pack(side = 'left', padx = 10)

frame1.pack()

# label
output_str = tk.StringVar()
label = ttk.Label(master = window, font = 'Calibri 16', text = 'Scale value', textvariable = output_str)
label.pack(pady = 5)

# run
window.mainloop()

我尝试测量时间(使用 timeit.timer_default() )并通过时间差计算速度,但只有在比例值发生变化后才会触发。 我想要一个独立的外部计时器来对值滑块进行采样并相应地更新速度。 我读过有关 threading.timer 的内容,但我不明白如何将它与主循环集成。

谢谢!

python multithreading tkinter timer scale
1个回答
0
投票

您可以使用 tkinter 的

after
方法来安排函数在给定的毫秒数后运行。您可以通过从
after
调用的函数中调用
after
来设置重复循环。

例如,考虑这个函数:

def sample(window, delay):
    # call sample(window, delay) after 'delay' milliseconds
    window.after(delay, sample, window, delay)

    # get the value and display it
    value = scalevar.get()
    print(f"Sample: {value:.2f}")

此函数将安排自己在 1000 毫秒(1 秒)后再次运行。接下来,它将获取当前值并将其打印到控制台。首先进行调度,以便函数中完成的处理量不会造成太大的漂移。

但是请注意,tkinter 不是实时系统,并且不能保证函数将在请求的时间精确运行。在这种情况下,唯一的保证是该函数将在 1000 毫秒后被调用。这可能意味着 1001 毫秒,也可能更长。由于 tkinter 是单线程的,因此在任何其他代码运行时都无法调用该函数。 如果您将此函数添加到代码中,然后调用它一次,它将继续每秒运行,直到您退出程序:

# run sample(window, 1000) window.mainloop()

	
© www.soinside.com 2019 - 2024. All rights reserved.