是否可以使用.after() - 方法与fps而不是定义毫秒。所以我想要一个标签描绘为6帧(60赫兹)。 - > root.after(6)而不是以ms为单位定义时间。
例如:
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)
话虽这么说,你可以做任何你想要尝试适应变化的数学。 - 布莱恩奥克利
沿着这条思路,保持循环的经过时间列表;然后从首选的UI刷新率中减去平均刷新率。迭代地向纳米尺度上的优选刷新率移动以考虑定时不规则性。
这将在大约1秒内实现并保持1ms的精度,这与after()方法允许的精确度相同,给定输入是milleseconds的整数。该方法适用于任何刻度尺寸低至millesecond。
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()