Tkinter – выборка значения шкалы каждые X секунд?

Итак, у меня есть базовый графический интерфейс Tkinter с ползунком масштабирования. Я хочу использовать таймер для выборки значения шкалы каждую 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, но не понимаю, как интегрировать его с основным циклом.

похоже, метод after — это именно то, что вам нужно

Danya K 26.06.2024 19:00

Отвечает ли это на ваш вопрос? Как запустить свой собственный код вместе с циклом событий Tkinter?. Единственная проблема с этим подходом заключается в том, что он не очень точен, но достаточно хорош для большинства задач.

TheLizzard 26.06.2024 21:19

Поможет ли вам оставить комментарий #scale.bind('<ButtonRelease-1>', scalerelease)?

toyota Supra 26.06.2024 21:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать метод after tkinter, чтобы запланировать запуск функции через заданное количество миллисекунд. Вы можете настроить повторяющийся цикл, вызвав 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 мс. Это может означать 1000,1 мс или больше. Поскольку tkinter является однопоточным, функцию нельзя вызвать во время выполнения другого кода.

Если вы добавите эту функцию в свой код, а затем вызовете ее один раз, она будет выполняться каждую секунду, пока вы не выйдете из программы:

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

Другие вопросы по теме