回答編集履歴
15
変数名変更 ( id -> after_id )
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
コメント誤記訂正
test
CHANGED
@@ -108,7 +108,7 @@
|
|
108
108
|
それと、代入しない変数は global宣言不要です。
|
109
109
|
|
110
110
|
```python
|
111
|
-
# 左回転時の基準時刻を取得し、
|
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
|
-
# 右回転時の基準時刻を取得し、
|
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 を共通化してはいかがでしょうか? コードを追記しました。
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
絶対時間のカウンタを作って、現在時刻から次の描画時刻までの差分を計算してafterの時間に指定すると正確な時間間隔で描画できるかと思います。
|
7
7
|
描画が追い付かなければ遅れていきますけど。
|
8
8
|
|
9
|
-
|
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に関するコメントを追記
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節に変更
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
|
-
|
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度描画する処理を追加
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 に変更
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
コメント修正
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秒で
|
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度目のクリックで回転処理が止まらなかったバグを修正
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
|
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
|
-
|
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
|
-
|
84
|
+
start_stop(-DEGREE_PER_TIME)
|
87
85
|
|
88
86
|
|
89
87
|
def finish(event=None):
|
6
マウスをクリックしてから72秒で360度回転するサンプルコードを書いてみました
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
コード修正中です少々お待ちください
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
マウスクリックで処理開始するように変更
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
|
-
|
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
|
-
|
23
|
+
WIDTH = root.winfo_screenwidth()
|
32
|
-
if (degree > 360):
|
33
|
-
root.quit()
|
34
|
-
|
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(
|
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度分表示する処理に変更
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
コメント修正
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
サンプルコード追記
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
|
+
|