#python #tkinter #progress-bar
#питон #ткинтеръ #индикатор выполнения #python #tkinter
Вопрос:
подробнее: то, что я пытаюсь создать, — это панель прогресса длиной в минуту, и как только минута заканчивается, она перезапускается и зацикливается. код вверху предназначен для автоматического запуска процесса при начале новой минуты. Проблема в том, что панель синхронизируется и запускается сама по себе просто отлично, но через минуту или две она начинает замедляться на пару секунд, самое запутанное в том, что она совсем не последовательна, она замедляется с разной скоростью каждый раз, когда я ее запускаю. Любая помощь была бы очень признательна.
вот мой код:
import time
from tkinter import *
import datetime as dt
from tkinter.ttk import *
now = dt.datetime.now()
sync_now = 'd:d:d' % (now.hour, now.minute, now.second)
sync_now_object = dt.datetime.strptime(sync_now, '%H:%M:%S').time()
second_of_day = int(now.hour * 60 * 60 now.minute * 60 now.second)
second_of_day = int(second_of_day / 60) * 60 60
hour = int(second_of_day / 60 / 60)
minute = int((second_of_day % (60 * 60)) / 60)
second = int(second_of_day % 60)
target_time = dt.time(hour, minute, second)
target_time_str = str(target_time)
print(target_time)
print(sync_now)
def time_to_num(time_str):
hh, mm , ss = map(int, time_str.split(':'))
return ss 60*(mm 60*hh)
difference_target_now=time_to_num(target_time_str)-time_to_num(sync_now)
print(difference_target_now)
after_difference = difference_target_now*1000
print(after_difference)
# creating Tk window
app = Tk()
app.wm_attributes('-topmost', 1)
# setting geometry of tk window
app.geometry("600x100")
# Using title() to display a message in
# the dialogue box of the message in the
# title bar.
app.title("")
progress = Progressbar(app, orient=HORIZONTAL,
length=600, mode='determinate')
def my_progress():
progress['maximum'] = 60
progress['value'] = 1
app.update()
time.sleep(1)
progress['value'] = 2
app.update()
time.sleep(1)
progress['value'] = 3
app.update()
time.sleep(1)
progress['value'] = 4
app.update()
time.sleep(1)
progress['value'] = 5
app.update()
time.sleep(1)
progress['value'] = 6
app.update()
time.sleep(1)
progress['value'] = 7
app.update()
time.sleep(1)
progress['value'] = 8
app.update()
time.sleep(1)
progress['value'] = 9
app.update()
time.sleep(1)
progress['value'] = 10
app.update()
time.sleep(1)
progress['value'] = 11
app.update()
time.sleep(1)
progress['value'] = 12
app.update()
time.sleep(1)
progress['value'] = 13
app.update()
time.sleep(1)
progress['value'] = 14
app.update()
time.sleep(1)
progress['value'] = 15
app.update()
time.sleep(1)
progress['value'] = 16
app.update()
time.sleep(1)
progress['value'] = 17
app.update()
time.sleep(1)
progress['value'] = 18
app.update()
time.sleep(1)
progress['value'] = 19
app.update()
time.sleep(1)
progress['value'] = 20
app.update()
time.sleep(1)
progress['value'] = 21
app.update()
time.sleep(1)
progress['value'] = 22
app.update()
time.sleep(1)
progress['value'] = 23
app.update()
time.sleep(1)
progress['value'] = 24
app.update()
time.sleep(1)
progress['value'] = 25
app.update()
time.sleep(1)
progress['value'] = 26
app.update()
time.sleep(1)
progress['value'] = 27
app.update()
time.sleep(1)
progress['value'] = 28
app.update()
time.sleep(1)
progress['value'] = 29
app.update()
time.sleep(1)
progress['value'] = 30
app.update()
time.sleep(1)
progress['value'] = 31
app.update()
time.sleep(1)
progress['value'] = 32
app.update()
time.sleep(1)
progress['value'] = 33
app.update()
time.sleep(1)
progress['value'] = 34
app.update()
time.sleep(1)
progress['value'] = 35
app.update()
time.sleep(1)
progress['value'] = 36
app.update()
time.sleep(1)
progress['value'] = 37
app.update()
time.sleep(1)
progress['value'] = 38
app.update()
time.sleep(1)
progress['value'] = 39
app.update()
time.sleep(1)
progress['value'] = 40
app.update()
time.sleep(1)
progress['value'] = 41
app.update()
time.sleep(1)
progress['value'] = 42
app.update()
time.sleep(1)
progress['value'] = 43
app.update()
time.sleep(1)
progress['value'] = 44
app.update()
time.sleep(1)
progress['value'] = 45
app.update()
time.sleep(1)
progress['value'] = 46
app.update()
time.sleep(1)
progress['value'] = 47
app.update()
time.sleep(1)
progress['value'] = 48
app.update()
time.sleep(1)
progress['value'] = 49
app.update()
time.sleep(1)
progress['value'] = 50
app.update()
time.sleep(1)
progress['value'] = 51
app.update()
time.sleep(1)
progress['value'] = 52
app.update()
time.sleep(1)
progress['value'] = 53
app.update()
time.sleep(1)
progress['value'] = 54
app.update()
time.sleep(1)
progress['value'] = 55
app.update()
time.sleep(1)
progress['value'] = 56
app.update()
time.sleep(1)
progress['value'] = 57
app.update()
time.sleep(1)
progress['value'] = 58
app.update()
time.sleep(1)
progress['value'] = 59
app.update()
time.sleep(1)
progress['value'] = 60
app.update()
time.sleep(1)
app.after(0, my_progress)
progress.pack()
app.after(after_difference, my_progress)
app.mainloop()
Комментарии:
1.
sleep()
будет блокироватьtkinter.mainloop()
, так что лучше используйтеafter()
вместо этого.
Ответ №1:
Две важные вещи:
time.sleep(1)
спит не менее одной секунды. Это не точный таймер.- Обновление индикатора выполнения также требует времени, что еще больше замедляет процесс
В вашем коде есть блоки, подобные этому:
progress['value'] = 1
app.update() # this takes time
time.sleep(1) # more than 1 second
Объединение 60 из них определенно займет больше минуты.
Чтобы получить больше точности, используйте разницу во времени между временем начала и текущим временем и соответствующим образом установите индикатор выполнения.
Вот обновленный код. Он проверяет разницу во времени каждые 1/10 секунды и обновляет индикатор выполнения.
def my_progress():
progress['maximum'] = 60
start = dt.datetime.now()
while True:
diff = (dt.datetime.now() - start).total_seconds() # seconds since bar start
progress['value'] = diff # can also use int(diff) to jump 1 sec
app.update()
time.sleep(0.1) # 1/10 second
if (diff > 60): # end of bar
start = dt.datetime.now() # restart progress