2020年2月29日土曜日

wxpython wx.EVT_SIZE, self.OnSize を使った描画のコード(スマイル顔が4つ)





wxpython dc  onsizeのイベントを使っておもしろいものをえがいているコード
を見つけたので、解析してみた。


wxpython/お絵かき5/onsize_my.py


 -*- coding: utf-8 -*-
#http://ja.voidcc.com/question/p-stizkibv-t.html

import wx

#wx.PyControl
#http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.Control.html
#これは、コントロールまたは「ウィジェット」の基本クラスです。
#コントロールは通常、ユーザー入力を処理したり、1つ以上のデータ項目を表
#示したりする小さなウィンドウです。

#でも以下のようにwx.Panelでしても各イベント動作変わらず
#ただし class Smiley(wx.PyControl)  を殺すのに
#       class Smiley2(wx.PyControl)  としただけではエラーとなる。
# 純粋に # で殺さないとだめ

class Smiley(wx.Panel):
    def __init__(self, parent):
        #wx.EXPANDでSmileyをつけるのでsizeはあまり関係ない
        wx.Panel.__init__(self, parent, size=(50,50))
        self.InitBuffer()    # new
        self.Bind(wx.EVT_SIZE, self.OnSize) # new
        self.Bind(wx.EVT_IDLE, self.OnIdle) # new
        self.Bind(wx.EVT_PAINT, self.OnPaint)

#class Smiley(wx.PyControl):
#   def __init__(self, parent, size=(50,50)):
#       #super(Smiley, self).__init__(parent,
#       #   size=size, style=wx.NO_BORDER)
#       self.InitBuffer()    # new
#       self.Bind(wx.EVT_SIZE, self.OnSize) # new
#       self.Bind(wx.EVT_IDLE, self.OnIdle) # new
#
#       self.Bind(wx.EVT_PAINT, self.OnPaint)

# new block
    def InitBuffer(self):
        print "InitBuffer"
        self.client_size = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(self.client_size.width, self.client_s
        dc = wx.BufferedDC(None, self.buffer)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        self.DrawImage(dc)
        self.reInitBuffer = False

    def OnPaint(self, event):
        print "OnPaint"
        wx.BufferedPaintDC(self, self.buffer)

    def OnSize(self, event):
        print "OnSize"
        self.reInitBuffer = True
        self.InitBuffer()

    #reInitBufferのフラグによって不必要にOnIdleが実行されないように
    #している
    def OnIdle(self, event):
        print "OnIdle"
        if self.reInitBuffer:
            self.InitBuffer()
            self.Refresh(False)

    def DrawImage(self, dc):

        # Get the working rectangle we can draw in
        rect = self.client_size

        # Find a square inside a rectangle (size of the client)
        #min:引数の最小値を得る
        min_side = min(rect.x, rect.y)
        rect.SetHeight(min_side)
        rect.SetWidth(min_side)

        # Setup the DC
        #線の色
        dc.SetPen(wx.BLACK_PEN) # for drawing lines/borders
        yellowbrush = wx.Brush(wx.Colour(255, 255, 0))
        #塗りつぶしの色(中の色)
        dc.SetBrush(yellowbrush) # Yellow fill

        # Find the center and draw the circle
        #顔面の描画
        #このSmileyの内に接する最大正方形の内に最大の円を黒で描く
        cx = rect.width/2
        cy = rect.width/2
        radius = min(rect.width, rect.height)/2
        #黒で円を描き中を黄色で塗る
        dc.DrawCircle(cx, cy, radius)

        # Give it some square blue eyes
        # Calc the size of the eyes 1/8th total
        #目の描画 青い四角で描く
        eyesz = (rect.width/8, rect.height/8)
        eyepos = (cx/2, cy/2)
        dc.SetBrush(wx.BLUE_BRUSH)
        dc.DrawRectangle(eyepos[0], eyepos[1],
            eyesz[0], eyesz[1])
        eyepos = (eyepos[0] + (cx - eyesz[0]), eyepos[1])
        dc.DrawRectangle(eyepos[0], eyepos[1],
            eyesz[0], eyesz[1])

        # Draw the smile
        #口の描画
        #DrawArc(self, xStart, yStart, xEnd, yEnd, xc, yc)
        #指定された開始点から指定された終了点まで弧を描きます。
        #描かれる弧は、(xc、yc)を中心とする円の弧です。
        #その開始点は(xStart、yStart)であるのに対して、
        #その終了点は(xc、yc)および(xEnd、yEnd)を通る線と
        #(xStart、yStart)を通る円の交点
        #です
        dc.SetBrush(yellowbrush)
        startpos = (cx/2, (cy/2) + cy)
        endpos = (cx + startpos[0], startpos[1])
        dc.DrawArc(startpos[0], startpos[1],
                        endpos[0], endpos[1], cx, cy)

        # Draw a yellow rectangle to cover up the
        # unwanted black lines from the wedge part of
        # our arc
        #上機械翻
        #円弧のくさび部分から不要な黒い線を覆うために黄色の長方形を描
        #画します
        #https://hannsihannsyou.blogspot.com/2018/12/wxpython6-wxpython6-h
        #TRANSPARENT_PENを実際使ったところなんの色でも描画されいなかった。

        #指定された左上隅とサイズで長方形を描画します。
        #現在のペンは輪郭に使用され、現在のブラシは形状を塗りつぶしま
        #す。
        #上の円から弧の端を結ぶ線を黄色で塗りつぶしている
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangle(startpos[0], cy,
            endpos[0] - startpos[0],
            startpos[1] - cy)
# end of a new block


class SmileyApp(wx.App):
    def OnInit(self):
        self.frame = SmileyFrame(None,
              title="Drawing Shapes",
              size=(300,400))
        self.frame.Show()
        return True

class SmileyFrame(wx.Frame):
    def __init__(self, parent, *args, **kwargs):
        wx.Frame.__init__(self, parent, *args, **kwargs)

        # Attributes
        self.panel = SmileyPanel(self)

        # Layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panel, 1, wx.EXPAND)
        self.SetSizer(sizer)

class SmileyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Layout
        self.__DoLayout()

    def __DoLayout(self):
        # Layout a grid of 4 smileys
        msizer = wx.GridSizer(2, 2, 0, 0)

        for x in range(4):
            #Smiley(PyControlクラス)を2×2のグリッドサイザーに
            #4個付ける
            smile = Smiley(self)
            msizer.Add(smile, 0, wx.EXPAND)
        self.SetSizer(msizer)

if __name__ == '__main__':
    app = SmileyApp(False)
    app.MainLoop()
                                                

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ページ

Featured Posts