描画系
プログラムの紹介
まずは簡単なプログラムの紹介。
四角形を drag 操作で追加することができ(図の赤)、追加しおわった四角形群(図の青)とともに、順番に表示しています。
コンポーネントとしては、真ん中に Graph
があり、あとボタンが付いているだけ。
今回は、クリック操作だけでなく、drag 操作を扱いたいので、enable_events=True, drag_submits=True
と設定しています。
あと、Graph は、文字通りグラフとか書けるように、座標系を自分で指定できるようになっています。今回は、ほぼつかっていませんが、各種チャートを書きたいときは便利かもです。
my_graph = sg.Graph((500, 500), (0, 0), (500, 500),
background_color='white',
enable_events=True, drag_submits=True,
key='graph')
MVC モデル
こういう描画系では、MVC モデルをつかうのが一般的です。
- Model: 論理的なデータ構造
- View: 論理データを GUI に表示したもの
- Control: 論理データに操作するためのもの
モデルの例
まずは Model。今回は、追加済みの四角形や、 drag 中の四角形が対応します。こんな感じ。
shapes = [] # 今までに配置した四角形を配置
drag_begin = () # drag 中は、drag 始点を格納、それ以外は empty
drag_current = () # drag 中は、drag 終点を格納、それ以外は empty
描画の例
View ですね。
Model に応じて描画をおこなうのですが、こんな感じ。
Graph
には draw_rectangle
など、図形を描画するためのメソッドが色々あるので、使ってください。
ポイントは、Event に応じて、毎回「差分」を書くんじゃなくて、最初に Erace()
して、全部書き直しているところです。まあ、追記する感じでつくってもいいのかもしれませんが。
def draw_canvas(self):
self.my_graph.Erase()
for left_top, right_bottom in self.shapes:
self.my_graph.draw_rectangle(left_top, right_bottom, fill_color='blue', line_color='white')
if self.drag_begin and self.drag_begin != self.drag_current:
self.my_graph.draw_rectangle(self.drag_begin, self.drag_current, fill_color='red', line_color='white')
マウスイベントの処理
Control ですね。 マウスイベントは、普通は click されたときに、その位置座標をつかってなにかすればいいんだと思います。 drag の場合は、drag 開始時点と終了時点を判別するため、mouse のボタンダウン、アップを判別しないといけません。
以下のようにmouse 操作に応じて、Model
に変更し、draw_canvas()
すれば基本大丈夫なはず。
def canvas_click(self, pos): # drag 開始・drag 中の処理
if not self.drag_begin:
self.drag_begin = pos
self.drag_current = pos
print(self.drag_begin, self.drag_current)
self.draw_canvas()
def canvas_click_up(self, pos): # drag 終点なら、図形として追加
self.shapes.append((pos, self.drag_begin))
self.drag_begin = self.drag_current = ()
self.draw_canvas()