#python #tkinter
#python #tkinter
Вопрос:
Я следил за этим руководством по созданию часов с помощью tkinter, и проблема, с которой я столкнулся, связана со строкой lbl.after(1000, time)
, которая заставляет функцию ждать одну секунду, а затем повторно запускать функцию времени.
Если вы запустите свою программу в 12:00:00.600, программа подождет одну секунду, а затем отобразит новое время через 600 микросекунд после 12:00: 01, а не ровно в 12:00: 01. Если у вас есть часы Windows и программа, работающие параллельно, часы Windows всегда будут немного быстрее. Я не уверен, как они заставили это работать в своем видео, я скопировал и вставил их код, и у меня все еще была та же проблема.
Я также видел чужой код, с помощью lbl.after(100, time)
которого функция перезапускается каждые .100 микросекунд, а не каждую секунду, и это вроде как работает, но время от времени все еще немного отключается.
В моей оригинальной программе, к которой я добавляю графический интерфейс с помощью tkinter, я использовал следующую функцию для отображения своего времени, и она была бы почти идеально синхронизирована с часами Windows.
import datetime as dt
def wait_until_new_second():
current_time = dt.datetime.now().time()
previous_time = current_time
while previous_time.second == current_time.second:
current_time = dt.datetime.now().time()
def display_clock():
while True:
wait_until_new_second()
print(dt.datetime.now().strftime('%H:%M:%S'))
display_clock()
Возможно ли, чтобы часы на tkinter были синхронизированы с часами Windows?
и / или
Есть ли способ сообщить tkinter подождать, используя мою wait_until_new_second()
функцию, вместо ожидания 1 секунды, что-то вроде lbl.after(wait_until_new_second, time)
?
Ответ №1:
Использование потока может быть почти (не полностью) синхронизировано с системными часами:
from datetime import datetime
import threading
import time
import tkinter as tk
root = tk.Tk()
clock = tk.StringVar()
tk.Label(root, textvariable=clock, font="Times 20 bold", fg='light green', bg="dark green").pack()
def tick():
while True:
now = datetime.now()
clock.set(now.strftime("%T"))
time.sleep(1-now.microsecond/1000000)
threading.Thread(target=tick, daemon=True).start()
root.mainloop()
Комментарии:
1. Спасибо! Это, вероятно, настолько близко, насколько я могу синхронизировать.
Ответ №2:
У меня была именно эта проблема: вот мое решение
import time
import tkinter as tk
trys = 0
def clicker():
global trys
timenow = time.time()
fraction = timenow % 1.0
if fraction < 0.025 :
root.after(950,clicker) #Tune here
ts = time.localtime()
milli = time.time() % 1.0
string = f'{ts.tm_year}_{ts.tm_mon:02d}_{ts.tm_mday:02d} {ts.tm_hour:02d}:{ts.tm_min:02d}:{(ts.tm_sec milli):06.3f}'
TimeLabel.config(text = string)
TrysLabel.config(text = f'{trys}')
trys = 0
############
############
## Do your on the second stuff here
############
############
else:
root.after(10,clicker) #Tune here
trys = 1
root = tk.Tk()
TimeLabel = tk.Label(root,text = '*********')
TimeLabel.pack()
TrysLabel = tk.Label(root,text = '****')
TrysLabel.pack()
clicker()
root.mainloop()
Это позволит сохранить функцию clicker в пределах 25 миллисекунд от настенных часов.
Вы можете настроить вызовы .after, чтобы сделать его немного ближе.
На моей машине это удерживало все в пределах примерно 12 миллисекунд. Самое главное (для моего приложения), что он делал то, что ему нужно было делать ровно один раз в секунду, как можно ближе ко второму.
В моем приложении я изменил время .after так, чтобы обычно было только 1 промах, а затем ударил по времени 10 миллисекунд спустя.
Весь смысл здесь заключался в том, чтобы свести к минимуму количество обратных вызовов, которые не представляли интереса.
Ответ №3:
Используйте этот код :
import sys
from tkinter import *
import time
def tick():
global time1
# get the current local time from the PC
time2 = time.strftime('%H:%M:%S')
# if time string has changed, update it
if time2 != time1:
time1 = time2
clock.config(text=time2)
# calls itself every 200 milliseconds
# to update the time display as needed
# could use >200 ms, but display gets jerky
clock.after(200, tick)
root = Tk()
time1 = ''
clock = Label(root, font=('times', 20, 'bold'), bg='red') clock.grid(row=0, column=0)
tick()
root.mainloop()
Это обновляется каждые 200 мс
Комментарии:
1. Почему вы импортируете
sys
, но нигде не используете?