2020年3月3日火曜日

wxpython マウスを筆にして絵を描く 親クラス作成



wxpython マウスを筆にして絵を描くhttps://hannsihannsyou.blogspot.com/2020/03/wxpython.html

上をdc描画動作、マウス動作を親クラスにしてコードを書き直した。


wxpython/お絵かき5/paintBuffer4.py



  1 # coding: UTF-8
  2
  3 #@@@ draw_hinagata.pyのモジュール化をしたが、使いにくいのでクラス
  4 #@@@ にしてその機能を子クラスとして使う事にする
  5 #@@@ PaintBuffer4.py dc描画イベント マウスイベント を受け持つ
  6
  7
  8 #参考サイト
  9 #まくまくpythonノート
 10 #https://maku77.github.io/python/wxpython/graphics.html
 11
 12
 13 import wx
 14
 15 # wx.Panelとwx.Windowの違いがわからない。
 16 # 別に変えても
 17 #class PaintBuffer(wx.Panel):
 18 class PaintBuffer(wx.Window):
 19     def __init__(self, parent):
 20         wx.Window.__init__(self, parent, -1)
 21         #wx.Panel.__init__(self, parent, -1)
 22
 23         self.color = "Green"
 24         self.thickness = 10
 25
 26         #创建一个画笔
 27         self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
 28         self.bf_size1 = None
 29         self.lines = []
 30         self.curLine = []
 31         self.pos = (0, 0)
 32         self.InitBuffer()
 33         self.buffer = None
 34         #イベント
 35         self.Bind(wx.EVT_PAINT, self.OnPaint)
 36         self.Bind(wx.EVT_SIZE, self.OnSize)
 37         self.Bind(wx.EVT_IDLE, self.OnIdle)
 38         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
 39         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
 40         self.Bind(wx.EVT_MOTION, self.OnMotion)
 41
 42
 43     """初期化"""
 44     def InitBuffer(self):
 45         print "InitBuffer"
 46         self.bf_size2 = self.GetClientSize()
 47
 48         # ウインドウサイズで、空の描画用バッファ(bitmap)を作成
 49         #ポインタとかおもった。可変長変数。
 50         #タプルを関数に渡すときに * を付けると、タプルの各要素を
 51         #関数の引数として展開されて渡される
 52         self.buffer = wx.EmptyBitmap(*self.bf_size2)
 53         dc = wx.BufferedDC(None, self.buffer)
 54         self.w_size2 = dc.GetSize()
 55         dc.SetBackground(wx.Brush('white'))
 56         # デバイスコンテキストでクリア、これがないと画面が真っ暗になる
 57         dc.Clear()
 58         #self.Draw(dc)  # 実際の描画処理
 59         # Falseを指定して背景を消さなくしたら画面のちらつきが出なくなった
 60         #self.Refresh(eraseBackground=False)
 61         self.DrawToBuffer(dc)
 62         self.reInitBuffer = False
 63
 64
 65     #EVT_PAINT イベントのハンドラの中で描画処理をバッファリングしたい場合
 66     #は、wx.BufferedDC の代わりに wx.BufferedPaintDC を使用します。
 67     def OnPaint(self, evt):
 68         print "OnPaint"
 69         dc = wx.BufferedPaintDC(self, self.buffer)
 70
 71     """ウインドウサイズが変更された時に呼ばれる処理"""
 72     def OnSize(self, evt):
 73         print "OnSize"
 74         self.InitBuffer()
 75
 76     #アイドル時に実行
 77     #reInitBufferのフラグによって無制限にアイドル時の実行を
 78     #さける
 79     def OnIdle(self, event):
 80         print "OnIdle"
 81         if self.reInitBuffer:
 82             self.InitBuffer()
 83
 84     def OnLeftDown(self, event):
 85         print "OnLeftDown"
 86         self.curLine = []
 87
 88         #获取鼠标位置
 89         self.pos = event.GetPositionTuple()
 90
 91         #https://uyamae.hatenadiary.org/entry/20090319/1237437401
 92         #前回やったラバーバンド処理は、マウスがウィンドウの外に出ると
 93         #挙動がおかしくなってしまいます。ウィンドウズのプログラミング
 94         #ではこういう場合にはマウスキャプチャーを使います。マウスカー
 95         #ソルが画面外に出てもマウスのイベントを受け取り続けると言うも
 96         #のです。
 97         #CaptureMouse()を呼び出してキャプチャー開始, ReleaseMouse()
 98         #を呼び出してキャプチャー終了です。
 99         self.CaptureMouse()
100
101     def OnLeftUp(self, event):
102         if self.HasCapture():
103             self.lines.append((self.color, self.thickness,
104                                     self.curLine, self.w_size1))
105             self.curLine = []
106             self.ReleaseMouse()
107
108     def OnMotion(self, event):
109         #下一行ウィンドウのサイズを得ようと思っただけで特にいらない
110         self.bf_size1 = self.GetClientSize()
111         if event.Dragging() and event.LeftIsDown():
112             dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
113             self.w_size1 = dc.GetSize()
114             self.drawMotion(dc, event)
115         event.Skip()
116
117     #マウスdownからupまでMotionしたところまで線をひく
118     #そのデータを配列に記録する
119     def drawMotion(self, dc, event):
120         dc.SetPen(self.pen)
121         newPos = event.GetPositionTuple()
122         #2要素のタプル同士を足すと4要素のタプルになる
123         coords = self.pos + newPos
124         dc.DrawLine(*coords)
125         self.curLine.append(coords)
126         self.pos = newPos
127
128
129     #描画
130     #wx.BufferedDC は、あるデバイス・コンテキストへの描画処 理をバッファ
131     #リングし、一度に描画内容を反映するようにしま す。 例えば、
132     #wx.ClientDC への連続した描画を wx.BufferedDC でバッファリングすれ
133     #ば、画面上での描画のち らつきを防ぐことができます。
134     def DrawToBuffer(self, dc):
135         print "DrawToBuffer"
136         pass
137
138
~                      

 1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3
  4 #@@@ペンでマウスの動きに沿って線を描く
  5 #@@@ paintBuffer4.pyはdcの描画に関するイベントを全て引き受ける
  6 #@@@ マウスイベントも引き受ける
  7
  8






wxpython/お絵かき5/pen_draw4.py

  9 #参考サイト
 10 #wxPython: 简单的绘图例子
 11 # http://www.jeepxie.net/article/761366.html
 12
 13 from paintBuffer4 import PaintBuffer
 14 import wx
 15
 16
 17 class MyFrame(wx.Frame):
 18     def __init__(self):
 19         wx.Frame.__init__(self, None, -1, "Panit Frame",
 20                 size = (800, 600))
 21         PaintWindow(self)
 22         self.Show()
 23
 24 class PaintWindow(PaintBuffer):
 25     def  __init__(self, parent):
 26         PaintBuffer.__init__(self, parent)
 27         print "PaintWindow"
 28
 29     #初期時、アイドル時 InitBuffer()から以下が実行される
 30     def DrawToBuffer(self, dc):
 31         print "DrawToBuffer"
 32         #ウィンドウの大きさが変わってもその相対位置にびょうが
 33         #しようとしたができない
 34         #floatをいれないと計算が0となっていた。ロス時間3h
 35         for colour, thickness, line, w_size1 in self.lines:
 36             pen = wx.Pen(colour, thickness, wx.SOLID)
 37             dc.SetPen(pen)
 38             w1, h1 = w_size1
 39             w2, h2 = self.w_size2
 40             for coords in line:
 41                 x1, y1, x2, y2 = coords
 42                 x1 = float(x1)
 43                 y1 = float(y1)
 44                 x2 = float(x2)
 45                 y2 = float(y2)
 46                 x1 = x1/w1*w2
 47                 x2 = x2/w1*w2
 48                 y1 = y1/h1*h2
 49                 y2 = y2/h1*h2
 50                 dc.DrawLine(x1, y1, x2, y2)
 51                 #dc.DrawLine(*coords)
 52
 53     #testコード
 54     def DrawLines2(self, dc):
 55         #dc.SetBackground(wx.Brush('white'))
 56
 57         #Clear  現在の背景ブラシを使用してデバイスコンテキストを
 58         #クリアします
 59         #これを実行しないと背景が真っ黒になる
 60         #dc.Clear()
 61
 62         dc.SetPen(wx.Pen('blue', 3))
 63         dc.DrawText('Hoge hoge', 10, 10)
 64         dc.DrawLine(10, 10, 200, 10)
 65         dw, dh = dc.GetSize()
 66         dc.SetPen(wx.Pen('blue', 3))
 67         dc.DrawCircle(dw/2, dh/2, 50)
 68         #以下のコードがないと最大化した時元の位置に円が描画したままと
 69         #なる
 70         #self.Refresh(False)
 71
 72 #   #使われていない
 73 #   def SetColor(self, color):
 74 #       self.color = color
 75 #       self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
 76 #      
 77 #   #使われていない
 78 #   def SetThickness(self, num):
 79 #       self.thickness = num
 80 #       self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
 81
 82
 83 if __name__ == '__main__':
 84     app = wx.App()
 85     MyFrame()
 86     app.MainLoop()
~                                                                           
~                                                                           
~                                                            
~                                                                           
:

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ブログ アーカイブ

ページ

Featured Posts