高橋メソッドマシーンぽいもの
新人研修のガイダンス用資料をつくらにゃ〜とあせりながらも六本木で働いていた元社長のアメブロを読んでたら、高橋メソッドの話が出てきて、そういやこんなのがあったな〜、これ使えばよくね?って思ったわけです。
で、高橋メソッドマシーンなるものの存在を知って、これオフラインで使えんかなぁと思ったのですがどうにもよく分からず、wxPython で自作してみました。
xrc のファイル(resource.xrc)
<?xml version="1.0" ?> <resource> <object class="wxFrame" name="MainFrame"> <title>Drawing</title> <centered>1</centered> <bg>#FFFFFF</bg> <font> <size>72</size> <style>normal</style> <weight>bold</weight> <underlined>0</underlined> <family>swiss</family> <face>MS ゴシック</face> <encoding>WINDOWS-1252</encoding> </font> <style>wxNO_BORDER</style> </object> </resource>
# encoding: utf-8 import wx import wx_utils from wx_utils import XRC,XRCID,XRCCTRL import re from optparse import OptionParser USAGE=u"""高橋メソッド マシーンぽいもの on wxPython SPACE で次へ 起動方法 >tmethod.py ファイル名 ファイル の中身 テキスト オンリー 空行の 改行で ページ切替 文字コードは UTF-8 のみ(?) 起動 オプション -e 文字コード ファイルの 文字コード 指定 UTF-8 以外もOK -c ページ カウント 表示 -s 自動「ご清聴 ありがとう ございました。」 操作方法 SPACE で次へ BackSpace で前へ Esc で終了 """ class MainFrame(wx.Frame): binder=wx_utils.bind_manager() # 初期化 def __init__(self,parent=None,text=USAGE,count=False): pre=wx.PreFrame() XRC().LoadOnFrame(pre,parent,'MainFrame') self.PostCreate(pre) self.binder.bindall(self) # 全画面表示 size=wx.ScreenDC().GetSize() self.SetSize(size) self.SetPosition(wx.Point(0,0)) #print size # キーイベント処理テーブル self.key_handler = { wx.WXK_ESCAPE : self.OnKey_Escape, wx.WXK_SPACE : self.OnKey_Space, wx.WXK_BACK : self.OnKey_Back, } # 表示する文字列 r_ret = re.compile(ur'\n\n+') if type(text)==str: text=unicode(text,"utf-8") self.text=[[y for y in x.split(u"\n")] for x in r_ret.split(text)] for text in self.text: if text[-1]=="": text.pop() self.current_idx=0 # フォント self.font = wx.Font(1,wx.DEFAULT,wx.NORMAL,wx.BOLD) # マージン self.margin = wx.Size(20, 20) # ページカウント self.pagecount = count # 描画イベントハンドラ @binder(wx.EVT_PAINT) def OnPaint(self, evt): # デバイスコンテキストの準備 dc = wx.BufferedPaintDC(self) dc.SetBackground(wx.WHITE_BRUSH) dc.Clear() dc.SetPen(wx.BLACK_PEN) # マージン ox = self.margin.GetWidth() oy = self.margin.GetHeight() # 画面サイズ取得 size = dc.GetSize() sw = size.GetWidth() sh = size.GetHeight() # 描画範囲計算 cw = sw - ox * 2 ch = sh - oy * 2 text = self.text[self.current_idx] # フォントサイズの決定 # 72 ポイントの場合のサイズを算出し self.font.SetPointSize(72) dc.SetFont(self.font) pw = 0 ph = 0 for t in text: w, h = dc.GetTextExtent(t) if pw < w: pw = w ph += h # 必要な範囲と最大範囲の比率から縦横のポイントサイズを算出し pw = 72 * cw / pw ph = 72 * ch / ph # 小さいほうをフォントのポイントサイズとする ptsize = min(pw, ph) # 新たなポイントサイズのフォントを設定 self.font.SetPointSize(ptsize) dc.SetFont(self.font) # 描画領域のサイズを確定し、描画位置の決定 pw = 0 ph = 0 for t in text: w, h = dc.GetTextExtent(t) if pw < w: pw = w ph += h py = (sh - ph) / 2 # 表示 for t in text: w,h = dc.GetTextExtent(t) dc.DrawText(t, (sw-w)/2, py) py += h # ページカウント if self.pagecount: self.font.SetPointSize(20) dc.SetFont(self.font) text = u"%d/%d"%(self.current_idx+1, len(self.text)) w, h = dc.GetTextExtent(text) dc.DrawText(text, sw-ox-w, sh-oy-h) # キーの処理 @binder(wx.EVT_KEY_UP) def OnKeyUp(self, evt): code = evt.GetKeyCode() # テーブルにキーコードがあれば処理する if code in self.key_handler: self.key_handler[code](evt) # ESC で終了 def OnKey_Escape(self, evt): self.Close() # スペースで進む def OnKey_Space(self, evt): if self.current_idx<len(self.text)-1: self.current_idx += 1 self.Refresh(False) # BackSpace で戻る def OnKey_Back(self, evt): if self.current_idx>0: self.current_idx -= 1 self.Refresh(False) def main(): from sys import argv import sys # 引数解析 parser = OptionParser() parser.add_option('-e','--encoding',dest='encoding',default='utf-8', type='string', help=u"入力ファイルのエンコーディング指定" ) parser.add_option('-d','--debug',dest='debugmode',default=False, action='store_true', help=u"デバッグモード" ) parser.add_option('-c','--counter',dest='pagecount',default=False, action='store_true', help=u"ページカウント表示" ) parser.add_option('-s','--auto-thanks',dest='autothanks',default=False, action='store_true', help=u"自動「ご清聴ありがとうございました」" ) (options, args) = parser.parse_args(argv[1:]) # 入力文字列の準備 if len(args)>0: text="" for fname in args: text+=unicode(open(fname).read(), options.encoding)+u"\n\n" text=text.strip() else: text=USAGE # 自動「ご清聴ありがとうございました」機能 if options.autothanks: text += u"\n\nご清聴\nありがとう\nございました。" # デバッグモード stdout=sys.stdout class X(object): def write(self, *args, **kwargs): pass if not options.debugmode: sys.stdout = X() app = wx.App() # アプリケーションのインスタンス作成 wx_utils.XrcInit() # リソースの初期化 frame = MainFrame(text=text,count=options.pagecount) # メインフレーム作成 app.SetTopWindow(frame) # アプリケーションのウィンドウ階層のトップに据える frame.Show(True) # メインフレームを表示 app.MainLoop() # メインフレーム終了待ち if __name__=="__main__": main()
wx_utils.pyのお世話になってます。結構さくっとできました。wxPython とwx_utils.py ちょうべんり!あとフォントの取り扱いの勉強になりました。72ポイントが1インチで1インチは96ピクセル*1!とか。
全画面表示オンリーでフォントサイズは自動調整で最大化してます。そして聴衆に先の見えない絶望感を与えないためのページカウンタ付き!引数なしの単発起動で使い方が表示されます。これは内蔵テキストによりデモをかねています。絵を表示したりできるように…とか一瞬考えましたがごてごてつけ始めると高橋メソッドのよさが失われるな、と思ってやめました。
これでしんじんけんしゅうがいだんすはばっちりだ!!(原稿さえ書けば)
*1:dpi は設定による