回答編集履歴

15

変数名変更 ( id -> after_id )

2022/09/08 06:32

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -114,7 +114,7 @@
114
114
  next_time = datetime.datetime.now()
115
115
  rotate(+1)
116
116
  def stop_L(event):
117
- root.after_cancel(id)
117
+ root.after_cancel(after_id)
118
118
  canvas.tag_bind("img_snow", "<ButtonPress-1>", press_L)
119
119
  canvas.bind("<ButtonRelease-1>", stop_L)
120
120
 
@@ -125,7 +125,7 @@
125
125
  next_time = datetime.datetime.now()
126
126
  rotate(-1)
127
127
  def stop_R(event):
128
- root.after_cancel(id)
128
+ root.after_cancel(after_id)
129
129
  canvas.tag_bind("img_snow", "<ButtonPress-3>", press_R)
130
130
  canvas.bind("<ButtonRelease-3>", stop_R)
131
131
 
@@ -134,7 +134,7 @@
134
134
  global next_time
135
135
  global tkimg
136
136
  global c
137
- global id
137
+ global after_id
138
138
  c = c + delta
139
139
  R = c / 10
140
140
  canvas.delete("all")
@@ -145,5 +145,5 @@
145
145
  next_time += interval
146
146
  now = datetime.datetime.now()
147
147
  delay_ms = int((next_time - now).total_seconds() * 1000)
148
- id = root.after(delay_ms, rotate, delta)
148
+ after_id = root.after(delay_ms, rotate, delta)
149
149
  ```

14

コメント誤記訂正

2022/09/08 01:50

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -108,7 +108,7 @@
108
108
  それと、代入しない変数は global宣言不要です。
109
109
 
110
110
  ```python
111
- # 左回転時の基準時刻を取得し、press_Lに渡す
111
+ # 左回転時の基準時刻を取得し、rotateに渡す
112
112
  def press_L(event):
113
113
  global next_time
114
114
  next_time = datetime.datetime.now()
@@ -119,7 +119,7 @@
119
119
  canvas.bind("<ButtonRelease-1>", stop_L)
120
120
 
121
121
 
122
- # 右回転時の基準時刻を取得し、press_Rに渡す
122
+ # 右回転時の基準時刻を取得し、rotateに渡す
123
123
  def press_R(event):
124
124
  global next_time
125
125
  next_time = datetime.datetime.now()

13

rotate_L と rotate_R を共通化してはいかがでしょうか? コードを追記しました。

2022/09/07 06:40

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -6,7 +6,7 @@
6
6
  絶対時間のカウンタを作って、現在時刻から次の描画時刻までの差分を計算してafterの時間に指定すると正確な時間間隔で描画できるかと思います。
7
7
  描画が追い付かなければ遅れていきますけど。
8
8
 
9
- 追記: マウスをクリックしてから72秒で360度回転するサンプルコードを書いてみました。
9
+ マウスをクリックしてから72秒で360度回転するサンプルコードを書いてみました。
10
10
 
11
11
  ```py
12
12
  import tkinter as tk
@@ -104,3 +104,46 @@
104
104
  root.mainloop()
105
105
  ```
106
106
 
107
+ 追記: rotate_L と rotate_R を共通化してはいかがでしょうか?
108
+ それと、代入しない変数は global宣言不要です。
109
+
110
+ ```python
111
+ # 左回転時の基準時刻を取得し、press_Lに渡す
112
+ def press_L(event):
113
+ global next_time
114
+ next_time = datetime.datetime.now()
115
+ rotate(+1)
116
+ def stop_L(event):
117
+ root.after_cancel(id)
118
+ canvas.tag_bind("img_snow", "<ButtonPress-1>", press_L)
119
+ canvas.bind("<ButtonRelease-1>", stop_L)
120
+
121
+
122
+ # 右回転時の基準時刻を取得し、press_Rに渡す
123
+ def press_R(event):
124
+ global next_time
125
+ next_time = datetime.datetime.now()
126
+ rotate(-1)
127
+ def stop_R(event):
128
+ root.after_cancel(id)
129
+ canvas.tag_bind("img_snow", "<ButtonPress-3>", press_R)
130
+ canvas.bind("<ButtonRelease-3>", stop_R)
131
+
132
+
133
+ def rotate(delta):
134
+ global next_time
135
+ global tkimg
136
+ global c
137
+ global id
138
+ c = c + delta
139
+ R = c / 10
140
+ canvas.delete("all")
141
+ IMG = img.rotate(R, resample=Image.BICUBIC)
142
+ tkimg = ImageTk.PhotoImage(IMG)
143
+ canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg, anchor="center", tags="img")
144
+ canvas.create_image(WIDTH/2, HEIGHT/2, image=tkimg_snow, anchor="center", tags="img_snow")
145
+ next_time += interval
146
+ now = datetime.datetime.now()
147
+ delay_ms = int((next_time - now).total_seconds() * 1000)
148
+ id = root.after(delay_ms, rotate, delta)
149
+ ```

12

変数cに関するコメントを追記

2022/09/07 03:13

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -34,7 +34,7 @@
34
34
  canvas = tk.Canvas(frame, width=WIDTH, height=HEIGHT, bg="black")
35
35
  canvas.place(x=0, y=0, width=WIDTH + 10, height=HEIGHT + 10)
36
36
 
37
- # "c"の初期値を定義
37
+ # "c"の初期値を定義 (浮動小数点数では誤差が発生するため1000倍した角度をcの値にする)
38
38
  c = 0
39
39
 
40
40
  DEGREE_PER_SEC = 5 # 1秒間に5 度回転、360度回転するのに360/5=72秒かかる

11

回転開始処理をelse節に変更

2022/09/07 02:57

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -73,12 +73,13 @@
73
73
  def start_stop(delta):
74
74
  global next_time, start_time, timer
75
75
  if timer:
76
- # 回転中なので回転停止
76
+ # 回転中なので回転停止処理
77
77
  root.after_cancel(timer)
78
78
  timer = None
79
- return
79
+ else:
80
+ # 回転開始処理
80
- next_time = start_time = datetime.datetime.now()
81
+ next_time = start_time = datetime.datetime.now()
81
- rotate(delta)
82
+ rotate(delta)
82
83
 
83
84
 
84
85
  def press_L(event):

10

時計の針のようなものを360度描画する処理を追加

2022/09/06 13:48

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -11,6 +11,7 @@
11
11
  ```py
12
12
  import tkinter as tk
13
13
  import datetime
14
+ from math import sin, cos, radians
14
15
 
15
16
 
16
17
  # 新規ウィンドウを作成
@@ -56,8 +57,11 @@
56
57
  finish()
57
58
  return
58
59
 
59
- # ここで描画処理するが動作確認のため
60
+ # ここで描画処理するが動作確認のため
60
61
  degree = c / 1000
62
+ radian = radians(degree)
63
+ canvas.delete("all")
64
+ canvas.create_line(100, 100, 100 + 50 * sin(radian), 100 - 50 * cos(radian), width=10, fill="red")
61
65
 
62
66
  # 次の絶対時刻までの差分を計算してタイマー設定
63
67
  now = datetime.datetime.now()

9

変数名を DEGREE_PER_SEC に変更

2022/09/06 10:25

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -36,22 +36,23 @@
36
36
  # "c"の初期値を定義
37
37
  c = 0
38
38
 
39
+ DEGREE_PER_SEC = 5 # 1秒間に5 度回転、360度回転するのに360/5=72秒かかる
40
+ TIMES_PER_SEC = 50 # 1秒間に50回描画 (20ミリ秒に1回描画)
41
+ DEGREE_PER_TIME = int(DEGREE_PER_SEC * 1000 / TIMES_PER_SEC) # 1000倍角
42
+ interval = datetime.timedelta(milliseconds=1000/TIMES_PER_SEC)
43
+
39
44
  start_time = datetime.datetime.now()
40
45
  next_time = None
41
46
  timer = None
42
- SECONDS_PER_ROUND = 72 # 72秒で360度回転
43
- TIMES_PER_SEC = 50 # 1秒間に50回描画 (20ミリ秒に1回描画)
44
- DEGREE_PER_TIME = int(360 * 1000 / SECONDS_PER_ROUND / TIMES_PER_SEC) # 1000倍角
45
- interval = datetime.timedelta(milliseconds=1000/TIMES_PER_SEC)
46
-
47
47
 
48
48
  def rotate(delta):
49
49
  global timer, next_time, c
50
50
  timer = None
51
51
  next_time += interval # 絶対時刻更新
52
52
  c += delta
53
+
54
+ #動作確認のため360度回転したら自動停止
53
55
  if not -360 * 1000 <= c <= 360 * 1000:
54
- #動作確認のため360度回転したら自動停止
55
56
  finish()
56
57
  return
57
58
 

8

コメント修正

2022/09/06 10:16

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -39,9 +39,9 @@
39
39
  start_time = datetime.datetime.now()
40
40
  next_time = None
41
41
  timer = None
42
- SECONDS_PER_ROUND = 72 # 72秒で1回転
42
+ SECONDS_PER_ROUND = 72 # 72秒で360度回転
43
43
  TIMES_PER_SEC = 50 # 1秒間に50回描画 (20ミリ秒に1回描画)
44
- DEGREE_PER_TIME = int(360 * 1000 / SECONDS_PER_ROUND / TIMES_PER_SEC) # 1000倍
44
+ DEGREE_PER_TIME = int(360 * 1000 / SECONDS_PER_ROUND / TIMES_PER_SEC) # 1000倍
45
45
  interval = datetime.timedelta(milliseconds=1000/TIMES_PER_SEC)
46
46
 
47
47
 

7

2度目のクリックで回転処理が止まらなかったバグを修正

2022/09/06 10:08

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -46,7 +46,8 @@
46
46
 
47
47
 
48
48
  def rotate(delta):
49
- global next_time, c
49
+ global timer, next_time, c
50
+ timer = None
50
51
  next_time += interval # 絶対時刻更新
51
52
  c += delta
52
53
  if not -360 * 1000 <= c <= 360 * 1000:
@@ -64,7 +65,7 @@
64
65
  timer = root.after(delay_ms, rotate, delta)
65
66
 
66
67
 
67
- def press_L(event):
68
+ def start_stop(delta):
68
69
  global next_time, start_time, timer
69
70
  if timer:
70
71
  # 回転中なので回転停止
@@ -72,18 +73,15 @@
72
73
  timer = None
73
74
  return
74
75
  next_time = start_time = datetime.datetime.now()
76
+ rotate(delta)
77
+
78
+
79
+ def press_L(event):
75
- rotate(+DEGREE_PER_TIME)
80
+ start_stop(DEGREE_PER_TIME)
76
81
 
77
82
 
78
83
  def press_R(event):
79
- global next_time, start_time, timer
80
- if timer:
81
- # 回転中なので回転停止
82
- root.after_cancel(timer)
83
- timer = None
84
- return
85
- next_time = start_time = datetime.datetime.now()
86
- rotate(-DEGREE_PER_TIME)
84
+ start_stop(-DEGREE_PER_TIME)
87
85
 
88
86
 
89
87
  def finish(event=None):

6

マウスをクリックしてから72秒で360度回転するサンプルコードを書いてみました

2022/09/06 10:00

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -6,9 +6,97 @@
6
6
  絶対時間のカウンタを作って、現在時刻から次の描画時刻までの差分を計算してafterの時間に指定すると正確な時間間隔で描画できるかと思います。
7
7
  描画が追い付かなければ遅れていきますけど。
8
8
 
9
- 追記: ダミーの重たい処理入れ、絶対時刻間隔繰り返すコードを書いてみました。
9
+ 追記: マウスクリックしから72秒360度回転るサンプルコードを書いてみました。
10
10
 
11
11
  ```py
12
+ import tkinter as tk
13
+ import datetime
12
14
 
15
+
16
+ # 新規ウィンドウを作成
17
+ root = tk.Tk()
18
+ root.title("SVV測定")
19
+ #root.attributes("-fullscreen", True)
20
+
21
+
22
+ # 画面サイズの指定
23
+ WIDTH = root.winfo_screenwidth()
24
+ HEIGHT = root.winfo_screenheight()
25
+
26
+
27
+ # ウィンドウ上にフレームを作成
28
+ frame = tk.Frame(root)
29
+ frame.place(x=-5, y=-5, width=WIDTH + 10, height=HEIGHT + 10)
30
+
31
+
32
+ # フレーム上に、キャンバスを作成
33
+ canvas = tk.Canvas(frame, width=WIDTH, height=HEIGHT, bg="black")
34
+ canvas.place(x=0, y=0, width=WIDTH + 10, height=HEIGHT + 10)
35
+
36
+ # "c"の初期値を定義
37
+ c = 0
38
+
39
+ start_time = datetime.datetime.now()
40
+ next_time = None
41
+ timer = None
42
+ SECONDS_PER_ROUND = 72 # 72秒で1回転
43
+ TIMES_PER_SEC = 50 # 1秒間に50回描画 (20ミリ秒に1回描画)
44
+ DEGREE_PER_TIME = int(360 * 1000 / SECONDS_PER_ROUND / TIMES_PER_SEC) # 1000倍
45
+ interval = datetime.timedelta(milliseconds=1000/TIMES_PER_SEC)
46
+
47
+
48
+ def rotate(delta):
49
+ global next_time, c
50
+ next_time += interval # 絶対時刻更新
51
+ c += delta
52
+ if not -360 * 1000 <= c <= 360 * 1000:
53
+ #動作確認のため360度回転したら自動停止
54
+ finish()
55
+ return
56
+
57
+ # ここで描画処理するが動作確認のため省略
58
+ degree = c / 1000
59
+
60
+ # 次の絶対時刻までの差分を計算してタイマー設定
61
+ now = datetime.datetime.now()
62
+ delay_ms = int((next_time - now).total_seconds() * 1000)
63
+ print(degree, delay_ms, now)
64
+ timer = root.after(delay_ms, rotate, delta)
65
+
66
+
67
+ def press_L(event):
68
+ global next_time, start_time, timer
69
+ if timer:
70
+ # 回転中なので回転停止
71
+ root.after_cancel(timer)
72
+ timer = None
73
+ return
74
+ next_time = start_time = datetime.datetime.now()
75
+ rotate(+DEGREE_PER_TIME)
76
+
77
+
78
+ def press_R(event):
79
+ global next_time, start_time, timer
80
+ if timer:
81
+ # 回転中なので回転停止
82
+ root.after_cancel(timer)
83
+ timer = None
84
+ return
85
+ next_time = start_time = datetime.datetime.now()
86
+ rotate(-DEGREE_PER_TIME)
87
+
88
+
89
+ def finish(event=None):
90
+ # Enterキーを押すことで全画面表示を終了し、回転角度を取得する
91
+ root.destroy()
92
+ degree = c / 1000
93
+ print(degree, "度回転するのにかかった秒数:", (datetime.datetime.now() - start_time).total_seconds())
94
+
95
+
96
+ canvas.bind("<ButtonPress-1>", press_L) # 左クリックで呼び出すイベント
97
+ canvas.bind("<ButtonPress-3>", press_R) # 右クリックで呼び出すイベント
98
+ root.bind("<Return>", finish) # Enterキーで呼び出すイベント
99
+
100
+ root.mainloop()
13
101
  ```
14
102
 

5

コード修正中です少々お待ちください

2022/09/06 09:17

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -9,86 +9,6 @@
9
9
  追記: ダミーの重たい処理を入れて、絶対時刻間隔で繰り返すコードを書いてみました。
10
10
 
11
11
  ```py
12
- import tkinter as tk
13
- import datetime
14
12
 
15
-
16
- # 新規ウィンドウを作成
17
- root = tk.Tk()
18
- root.title("SVV測定")
19
- #root.attributes("-fullscreen", True)
20
-
21
-
22
- # 画面サイズの指定
23
- WIDTH = root.winfo_screenwidth()
24
- HEIGHT = root.winfo_screenheight()
25
-
26
-
27
- # ウィンドウ上にフレームを作成
28
- frame = tk.Frame(root)
29
- frame.place(x=-5, y=-5, width=WIDTH + 10, height=HEIGHT + 10)
30
-
31
-
32
- # フレーム上に、キャンバスを作成
33
- canvas = tk.Canvas(frame, width=WIDTH, height=HEIGHT, bg="black")
34
- canvas.place(x=0, y=0, width=WIDTH + 10, height=HEIGHT + 10)
35
-
36
- # "c"の初期値を定義
37
- c = 0
38
-
39
- timer = None
40
-
41
- # 角速度の指定
42
- interval = datetime.timedelta(milliseconds=20)
43
-
44
- # イベントが発生したときの処理
45
-
46
-
47
- def press_L(event):
48
- global timer, c, next_time
49
- if timer:
50
- root.after_cancel(timer)
51
- timer = None
52
- c += 1
53
- next_time = datetime.datetime.now() + interval
54
- # 左クリックの回数によって、左回転させる
55
- now = datetime.datetime.now()
56
- delay_ms = int((next_time - now).total_seconds() * 1000)
57
- print(c, delay_ms, now)
58
- timer = root.after(delay_ms, press_L, None)
59
-
60
-
61
- def press_R(event):
62
- global timer, c, next_time
63
- if timer:
64
- root.after_cancel(timer)
65
- timer = None
66
- c -= 1
67
- next_time = datetime.datetime.now() + interval
68
- # 右クリックの回数によって、右回転させる
69
- now = datetime.datetime.now()
70
- delay_ms = int((next_time - now).total_seconds() * 1000)
71
- print(c, delay_ms, now)
72
- timer = root.after(delay_ms, press_R, None)
73
-
74
-
75
- def finish(event):
76
- # Enterキーを押すことで全画面表示を終了し、回転角度を取得する
77
- root.destroy()
78
- print(-c)
79
-
80
-
81
- # 左クリックで呼び出すイベント
82
- canvas.bind("<ButtonPress-1>", press_L)
83
-
84
- # 右クリックで呼び出すイベント
85
- canvas.bind("<ButtonPress-3>", press_R)
86
-
87
- # Enterキーで呼び出すイベント
88
- root.bind("<Return>", finish)
89
-
90
-
91
- # メインループ
92
- root.mainloop()
93
13
  ```
94
14
 

4

マウスクリックで処理開始するように変更

2022/09/06 09:13

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -11,29 +11,84 @@
11
11
  ```py
12
12
  import tkinter as tk
13
13
  import datetime
14
- import time
15
- import random
16
14
 
15
+
16
+ # 新規ウィンドウを作成
17
17
  root = tk.Tk()
18
+ root.title("SVV測定")
19
+ #root.attributes("-fullscreen", True)
18
20
 
19
- degree = 0
20
- degree_per_second = 360 / 72
21
- interval = datetime.timedelta(seconds=1)
22
- next_time = datetime.datetime.now() + interval # 次の絶対時刻
23
21
 
24
- def repeat():
22
+ # 画面サイズの指定
25
- global next_time, degree
26
- time.sleep(random.randint(100, 500) / 1000) # ダミーの重たい処理
27
- now = datetime.datetime.now() # 現在時刻と
28
- delay_ms = int((next_time - now).total_seconds() * 1000) # 次の絶対時刻までの差分
29
- print(f'{degree:3g} {next_time} = {now} + {delay_ms / 1000:.3f}')
30
- next_time += interval # 次の絶対時刻を更新
31
- degree += degree_per_second
23
+ WIDTH = root.winfo_screenwidth()
32
- if (degree > 360):
33
- root.quit()
34
- root.after(delay_ms, repeat)
24
+ HEIGHT = root.winfo_screenheight()
35
25
 
26
+
27
+ # ウィンドウ上にフレームを作成
28
+ frame = tk.Frame(root)
29
+ frame.place(x=-5, y=-5, width=WIDTH + 10, height=HEIGHT + 10)
30
+
31
+
32
+ # フレーム上に、キャンバスを作成
33
+ canvas = tk.Canvas(frame, width=WIDTH, height=HEIGHT, bg="black")
34
+ canvas.place(x=0, y=0, width=WIDTH + 10, height=HEIGHT + 10)
35
+
36
+ # "c"の初期値を定義
37
+ c = 0
38
+
39
+ timer = None
40
+
41
+ # 角速度の指定
42
+ interval = datetime.timedelta(milliseconds=20)
43
+
44
+ # イベントが発生したときの処理
45
+
46
+
47
+ def press_L(event):
48
+ global timer, c, next_time
49
+ if timer:
36
- root.after(100, repeat)
50
+ root.after_cancel(timer)
51
+ timer = None
52
+ c += 1
53
+ next_time = datetime.datetime.now() + interval
54
+ # 左クリックの回数によって、左回転させる
55
+ now = datetime.datetime.now()
56
+ delay_ms = int((next_time - now).total_seconds() * 1000)
57
+ print(c, delay_ms, now)
58
+ timer = root.after(delay_ms, press_L, None)
59
+
60
+
61
+ def press_R(event):
62
+ global timer, c, next_time
63
+ if timer:
64
+ root.after_cancel(timer)
65
+ timer = None
66
+ c -= 1
67
+ next_time = datetime.datetime.now() + interval
68
+ # 右クリックの回数によって、右回転させる
69
+ now = datetime.datetime.now()
70
+ delay_ms = int((next_time - now).total_seconds() * 1000)
71
+ print(c, delay_ms, now)
72
+ timer = root.after(delay_ms, press_R, None)
73
+
74
+
75
+ def finish(event):
76
+ # Enterキーを押すことで全画面表示を終了し、回転角度を取得する
77
+ root.destroy()
78
+ print(-c)
79
+
80
+
81
+ # 左クリックで呼び出すイベント
82
+ canvas.bind("<ButtonPress-1>", press_L)
83
+
84
+ # 右クリックで呼び出すイベント
85
+ canvas.bind("<ButtonPress-3>", press_R)
86
+
87
+ # Enterキーで呼び出すイベント
88
+ root.bind("<Return>", finish)
89
+
90
+
91
+ # メインループ
37
92
  root.mainloop()
38
93
  ```
39
94
 

3

1秒間隔で72秒かけて360度分表示する処理に変更

2022/09/06 07:58

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -16,17 +16,22 @@
16
16
 
17
17
  root = tk.Tk()
18
18
 
19
+ degree = 0
20
+ degree_per_second = 360 / 72
19
21
  interval = datetime.timedelta(seconds=1)
20
22
  next_time = datetime.datetime.now() + interval # 次の絶対時刻
21
23
 
22
24
  def repeat():
23
- global next_time
25
+ global next_time, degree
24
26
  time.sleep(random.randint(100, 500) / 1000) # ダミーの重たい処理
25
27
  now = datetime.datetime.now() # 現在時刻と
26
28
  delay_ms = int((next_time - now).total_seconds() * 1000) # 次の絶対時刻までの差分
27
- print(f'{next_time} = {now} + {delay_ms / 1000:.3f}')
29
+ print(f'{degree:3g} {next_time} = {now} + {delay_ms / 1000:.3f}')
30
+ next_time += interval # 次の絶対時刻を更新
31
+ degree += degree_per_second
32
+ if (degree > 360):
33
+ root.quit()
28
34
  root.after(delay_ms, repeat)
29
- next_time += interval # 次の絶対時刻を更新
30
35
 
31
36
  root.after(100, repeat)
32
37
  root.mainloop()

2

コメント修正

2022/09/05 13:07

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -23,7 +23,7 @@
23
23
  global next_time
24
24
  time.sleep(random.randint(100, 500) / 1000) # ダミーの重たい処理
25
25
  now = datetime.datetime.now() # 現在時刻と
26
- delay_ms = int((next_time - now).total_seconds() * 1000) # 次の絶対時刻までの差分を計算
26
+ delay_ms = int((next_time - now).total_seconds() * 1000) # 次の絶対時刻までの差分
27
27
  print(f'{next_time} = {now} + {delay_ms / 1000:.3f}')
28
28
  root.after(delay_ms, repeat)
29
29
  next_time += interval # 次の絶対時刻を更新

1

サンプルコード追記

2022/09/05 13:06

投稿

shiracamus
shiracamus

スコア5406

test CHANGED
@@ -5,3 +5,30 @@
5
5
  それと、テレビ放送でも1秒間に30コマ(33ミリ秒/コマ)、ゲームで秒60コマ(16ミリ秒/コマ)や120コマ(8ミリ秒/コマ)の描画でアニメーションしています。
6
6
  絶対時間のカウンタを作って、現在時刻から次の描画時刻までの差分を計算してafterの時間に指定すると正確な時間間隔で描画できるかと思います。
7
7
  描画が追い付かなければ遅れていきますけど。
8
+
9
+ 追記: ダミーの重たい処理を入れて、絶対時刻間隔で繰り返すコードを書いてみました。
10
+
11
+ ```py
12
+ import tkinter as tk
13
+ import datetime
14
+ import time
15
+ import random
16
+
17
+ root = tk.Tk()
18
+
19
+ interval = datetime.timedelta(seconds=1)
20
+ next_time = datetime.datetime.now() + interval # 次の絶対時刻
21
+
22
+ def repeat():
23
+ global next_time
24
+ time.sleep(random.randint(100, 500) / 1000) # ダミーの重たい処理
25
+ now = datetime.datetime.now() # 現在時刻と
26
+ delay_ms = int((next_time - now).total_seconds() * 1000) # 次の絶対時刻までの差分を計算
27
+ print(f'{next_time} = {now} + {delay_ms / 1000:.3f}')
28
+ root.after(delay_ms, repeat)
29
+ next_time += interval # 次の絶対時刻を更新
30
+
31
+ root.after(100, repeat)
32
+ root.mainloop()
33
+ ```
34
+