Tkinterで描画情報を設定した時間ごとに取得する
はじめに
PythonでGUIプログラムを書けるライブラリTkinter.
このライブラリでは、中にあるCanvasを使って絵を描く事が出来る.
Canvasを使って絵を描く機会は人間誰しもあると思うが、Canvasに書いた情報を設定した時間ごとに取得するというプログラムは調べてもはっきりとわからなかった.
備忘録も兼ねて、プログラムを書いていく.
ちなみにCanvasを使って絵を描くというプログラム自体は以下のサイトを参考にした.
Pythonのcanvasにマウスで線を描いてみる
実行環境
- macOS Catalina 10.15.3
- tkinter 8.6
- Pillow 6.2.1
コード
#!/usr/bin/env python
# -*- coding: utf8 -*-
import tkinter
import time
from PIL import Image, ImageDraw
class Application(tkinter.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title('Measure the time to draw')
self.create_variables()
self.create_widgets()
self.pack()
def create_widgets(self):
self.draw_canvas = tkinter.Canvas(self, bg='white', width=self.img_size[0], height=self.img_size[1])
self.draw_canvas.grid(row=1, column=0, columnspan=4)
self.draw_canvas.bind('<Button-1>', self.start)
self.draw_canvas.bind('<B1-Motion>', self.paint)
self.draw_canvas.bind('<ButtonRelease-1>', self.reset)
def create_variables(self):
self.img_size = (600, 600)
self.old_x, self.old_y = None, None
self.color = 'black'
self.pen_width = 5.0
self.im = Image.new('RGB', self.img_size, 'white')
self.draw = ImageDraw.Draw(self.im)
self.tick_time = 30
self.timer_id = None
self.start_time = None
#methods
def start(self, event):
if self.timer_id is None:
self.timer_start()
self.draw_canvas.create_line(event.x, event.y, event.x, event.y, width=self.pen_width, fill=self.color, capstyle="round", smooth=True, splinesteps=36)
self.draw.line((event.x, event.y, event.x, event.y), fill=self.color, width=int(self.pen_width))
self.old_x, self.old_y = event.x, event.y
def paint(self, event):
if self.old_x and self.old_y:
self.draw_canvas.create_line(self.old_x, self.old_y, event.x, event.y, width=self.pen_width, fill=self.color, capstyle="round", smooth=True, splinesteps=36)
self.draw.line((self.old_x, self.old_y, event.x, event.y), fill=self.color, width=int(self.pen_width))
self.old_x, self.old_y = event.x, event.y
def reset(self, event):
self.old_x, self.old_y = None, None
self.timer_reset()
#timer
def timer_start(self):
if self.timer_id is not None:
self.after_cancel(self.timer_id)
self.start_time = time.time()
self.timer_id = self.after(self.tick_time, self.timer_count)
def timer_count(self):
t = time.time() - self.start_time
x = self.old_x if self.old_x is not None else -1
y = self.old_y if self.old_y is not None else -1
print("経過時間:%f , X位置 %d, Y位置 %d" % (t, x, y))
self.timer_id = self.after(self.tick_time, self.timer_count)
def timer_reset(self):
if self.timer_id is None:
return
self.after_cancel(self.timer_id)
self.timer_id = None
if __name__ == "__main__":
root = tkinter.Tk()
app = Application(master=root)
app.mainloop()
実行結果
#!/usr/bin/env python
# -*- coding: utf8 -*-
import tkinter
import time
from PIL import Image, ImageDraw
class Application(tkinter.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title('Measure the time to draw')
self.create_variables()
self.create_widgets()
self.pack()
def create_widgets(self):
self.draw_canvas = tkinter.Canvas(self, bg='white', width=self.img_size[0], height=self.img_size[1])
self.draw_canvas.grid(row=1, column=0, columnspan=4)
self.draw_canvas.bind('<Button-1>', self.start)
self.draw_canvas.bind('<B1-Motion>', self.paint)
self.draw_canvas.bind('<ButtonRelease-1>', self.reset)
def create_variables(self):
self.img_size = (600, 600)
self.old_x, self.old_y = None, None
self.color = 'black'
self.pen_width = 5.0
self.im = Image.new('RGB', self.img_size, 'white')
self.draw = ImageDraw.Draw(self.im)
self.tick_time = 30
self.timer_id = None
self.start_time = None
#methods
def start(self, event):
if self.timer_id is None:
self.timer_start()
self.draw_canvas.create_line(event.x, event.y, event.x, event.y, width=self.pen_width, fill=self.color, capstyle="round", smooth=True, splinesteps=36)
self.draw.line((event.x, event.y, event.x, event.y), fill=self.color, width=int(self.pen_width))
self.old_x, self.old_y = event.x, event.y
def paint(self, event):
if self.old_x and self.old_y:
self.draw_canvas.create_line(self.old_x, self.old_y, event.x, event.y, width=self.pen_width, fill=self.color, capstyle="round", smooth=True, splinesteps=36)
self.draw.line((self.old_x, self.old_y, event.x, event.y), fill=self.color, width=int(self.pen_width))
self.old_x, self.old_y = event.x, event.y
def reset(self, event):
self.old_x, self.old_y = None, None
self.timer_reset()
#timer
def timer_start(self):
if self.timer_id is not None:
self.after_cancel(self.timer_id)
self.start_time = time.time()
self.timer_id = self.after(self.tick_time, self.timer_count)
def timer_count(self):
t = time.time() - self.start_time
x = self.old_x if self.old_x is not None else -1
y = self.old_y if self.old_y is not None else -1
print("経過時間:%f , X位置 %d, Y位置 %d" % (t, x, y))
self.timer_id = self.after(self.tick_time, self.timer_count)
def timer_reset(self):
if self.timer_id is None:
return
self.after_cancel(self.timer_id)
self.timer_id = None
if __name__ == "__main__":
root = tkinter.Tk()
app = Application(master=root)
app.mainloop()
実行結果
実行してみると、絵を描く為のキャンバスが出てくる.
このキャンバスにマウスで絵を描いてみると、ターミナルに
* 書き始めからの経過時間(/ミリ秒)
* X位置
* Y位置
が表示されるというプログラムになっている.
解説
タイマーの挙動に関する関数は、timer_start()、timer_count()、timer_reset()で定義されている.
これらの関数はCanvasにbindされたstart()、 reset()に応じて呼び出されて、after()関数によってtick_time変数に定義された時間ごとに、timer_count()を呼び出して現在の描画情報が得られるというようになっている
最後に
初めての記事作成だった.
文字を書いていて、どんな書き方をしてるのかをどう調査するというところで引っ掛かったところなので、このプログラムは手書きのオンライン情報を取得したいといった状況に役立てれば良いなと考えている.
参考
Author And Source
この問題について(Tkinterで描画情報を設定した時間ごとに取得する), 我々は、より多くの情報をここで見つけました https://qiita.com/johnpapapa/items/cebfac899b131b84351f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .