Python - Tkinter - Использование метода after и cotroll для частоты кадров - PullRequest
0 голосов
/ 10 мая 2018

возможно ли использовать метод .after () с fps вместо определения миллисекунд.Поэтому я хочу, чтобы метка была изображена для 6 кадров (60 Гц).-> root.after (6) вместо определения времени в мс.

Например:

root = tk.Tk()

ListofStimuli = ["\u00B6","\u0126"]

labelprint = tk.Label(root,text="+", font = ('Sans','80','bold'), bg = "white")
labelprint.place(relx=.5, rely=.5, anchor="c")


for elem in ListofStimuli:

    labelprint.config(text=elem) 
    root.after(100, lambda: var.set(0))
    root.wait_variable(var)

1 Ответ

0 голосов
/ 14 февраля 2019

Как говорится, вы можете делать любую математику, какую захотите приспособить для отклонений. - Брайан Оукли

В соответствии с этой мыслью ведите список прошедших времен вашего цикла; затем вычтите среднее обновление из предпочитаемой вами частоты обновления пользовательского интерфейса. Итеративно переходите к предпочтительной частоте обновления по нано-шкале, чтобы учесть нарушения синхронизации.

Это позволит достичь и поддерживать точность в 1 мс в течение примерно 1 секунды, что так же точно, как позволяет метод after (), учитывая, что входные данные представляют собой целые числа миллисекунд. Метод будет работать для любого размера тика вплоть до миллисекунд.

import time
import tkinter as tk

UI_REFRESH = 100 # your preferred refresh rate in milleseconds
UI_DELTA = 0.000001 # nanosecond scale iterative filter step size
UI_DEPTH = 10 # depth of ui_refreshes moving average

def animate():

    global last_refresh, ui_refreshes, last_refresh, ui_delta

    print("\033c") # clear terminal    
    # keep moving average of UI_REFRESH timing
    now = time.time()
    ui_refreshes.append(now - last_refresh)
    ui_refreshes = ui_refreshes[-UI_DEPTH:]
    ui_refresh = sum(ui_refreshes) / len(ui_refreshes)
    last_refresh = now

    # filter nanosecond scale timing oddities iteratively
    # both as they arise due to load and between various systems
    refresh_error = abs(UI_REFRESH_SEC-ui_refresh)
    if float('%.5f' % ui_refresh) < (UI_REFRESH_SEC):
        ui_delta += UI_DELTA
    if float('%.5f' % ui_refresh) > (UI_REFRESH_SEC):
        ui_delta -= UI_DELTA

    # do whatever your loop does
    # note this must take less time than your refresh rate!!
    print(  int(time.time()),
            ('%.6f' % ui_refresh),
            ('%.6f' % refresh_error),
            ('%.4f' % round(ui_refresh, 4)),
            int(1000*round(ui_refresh, 4)))

    # set perfect UI_REFRESH timing
    pause = int(1000 *
                min(UI_REFRESH_SEC, (
                    max(0, (
                        2 * UI_REFRESH_SEC - ui_refresh + ui_delta)))))
    master.after(pause, animate)

print("\033c") # clear terminal
UI_REFRESH_SEC = UI_REFRESH/1000
ui_refreshes = []
last_refresh = time.time()
ui_delta = 0
master = tk.Tk()
master.after(0, animate)
master.mainloop()
...