3 件 見つかりました。
昔ビデオ信号のキャプチャ用プログラムをゴリゴリ書いてえらく苦労したことがある。pythonならもっと簡単なのではと思い調べた。
環境:Windows MCE, python 2.5, Princetonデジ造PCA-DAV2(ドライバのみインストール、ShowBizは入れてない), WAT-502B
案の定、すごいのがあった。
VideoCapture
以下だけで、とりあえずの静止画像保存ができる。超簡単。
from VideoCapture import Device cam = Device() # "devnum"引数でデバイスを選べる cam.saveSnapshot('hello.jpg')
import wx, os, sys import Image,ImageDraw from VideoCapture import Device class MainWindow(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self, parent, wx.ID_ANY, title, size = (400,400)) self.cam = Device() wx.EVT_PAINT(self, self.OnPaint) wx.EVT_IDLE(self, self.OnIdle) self.Show(True) def OnIdle(self, evt): self.Refresh(False) def OnPaint(self, evt): dc = wx.PaintDC(self) dc.DrawBitmap(self.GetBmp1(), 0, 0, True) def GetBmp1(self): image_pil = self.cam.getImage() image_wx = wx.EmptyImage(image_pil.size[0],image_pil.size[1]) image_wx.SetData(image_pil.convert('RGB').tostring()) return image_wx.ConvertToBitmap() def GetBmp2(self): buffer, width, height = self.cam.getBuffer() image_wx = wx.EmptyImage(width, height) image_wx.SetData(buffer) return image_wx.ConvertToBitmap() app = wx.PySimpleApp() frame = MainWindow(None, -1, "Imaging") app.MainLoop()
WWWで見たサンプルコードを自分用に書き直してメモ。
import wx clp = wx.Clipboard() clp.Open() if clp.IsSupported(wx.DataFormat(wx.DF_BITMAP)): do = wx.BitmapDataObject() clp.GetData(do) bmp = do.GetBitmap() bmp.SaveFile('clp.png', wx.BITMAP_TYPE_PNG) print 'finished' else: print 'bitmap is not available on the clipboard' clp.Close()win32apiとlibpngの直叩きで同じことをした経験があるが、(wx)Pythonであまりにも簡単に出来て驚嘆した。あの苦労は何だったのだろう。。。
ちょっとしたGUIプログラムをパッと作りたい時にどうするか。
C/C++はちょっとやるだけには面倒なので、もっと何も考えないでいいやつにしたい。
Visual Basicは文法面がちょっと気にくわない。.NETはよくわからない。
じゃあスクリプト言語でということになるが、何かと文書やツール類が充実してるpythonが良さそう。
で、WindowsでpythonをGUIから使う/呼ぶためにはどうすればいいのか調べたことをメモする。
まずwxWidgetsというものがある。これは言語やOSの違いを吸収してくれるGUIツールキット。これをpythonからいじるためのものがwxPythonである。これが「pythonでGUI」に必要な条件(他のツールキットももちろんある)。
で、GUI設計においてはデザイナの使用がキモなので、このためのツールを探した。そしてwxGladeなるものとXRCedなるものを発見した。
前提(サイザー)
wxWidgetsにおいてはサイザーなるオブジェクトがある。これはウィンドウと各コントロールの相対的な大きさや位置関係をよしなに面倒見てくれるオブジェクト。wxWidgetにおいては、コントロールの配置はサイザーの使用が原則のようだ。wxGladeではサイザーが無いとコントロールが配置できない。XRCedではできるみたい。
wxGlade
これはコントロールを比較的直観的に、つまりはVisual Studioのように配置できるため、画面などもそこそこ見慣れたものが出てくる。GUIの情報の出力形式はXRC(後述)、python、C++など色々と選べる。インストーラでインストールできた。
wxWidgets でクロスプラットフォーム GUIアプリを作ろう
XRCed
これはVisual Studioなどと比べ抽象的に(と感じた)コントロールを配置するもので、最初は面喰らったがサイザーの概念が多少わかるとこれはそれほど苦にならなかった。GUI情報の出力はXRCのみ。wxPythonで記述されており、wxPythonに付属。
PythonMatrix:XRCedの使い方
ちょっと触っただけだが、どちらも優れていて使い易そうだなと感じた。だが、wxGladeは複数の出力形式ができ、イベントハンドラ名の記述もできる点で優れているのかなあと感じた。GUI部分を変更して上書き保存しても、ハンドラの定義部分はうまく残してくれるようだ。
順番は前後したが、wxPythonにおいてGUIの記述は2通りある:ソースに直接コントロールの配置など全て記述するのと、GUI情報のみXMLファイルに格納し(これをXRCというようだ)別途読み込むこと。前者はソースひとつで完結する単純明瞭さがメリットで、後者はインターフェースと処理のロジックを分離できるのがメリット。
wxGladeでハンドラを指定してpython形式で出力するとハンドラの記述も終わっていて便利。一方でXRCで出力すると、後に別途自分でpythonソースにハンドラを記述(「このボタン押下時この関数を呼べ」)する必要があってひと手間増える(GUIとソースの分離がXRCの本質なので、まあこれは当然)。XRCedは出力がXRCなので、当然同様な事情である。
パッと作成するシンプルさの観点からは、wxGladeを使用してpythonで出力するのが良さそうというのが今日の結論。
なお、XRCで記述したコントロールに対しイベントハンドラを記述するには以下のようにする。XRC Tutorial
<?xml version="1.0" encoding="cp932"?> <resource> <object class="wxFrame" name="myframe"> <title>myframe_title</title> <object class="wxPanel" name="mypanel"> <object class="wxBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <object class="wxButton" name="mybutton"> <label>mybutton_label</label> </object> </object> </object> </object> </object> </resource>
import wx from wx import xrc class MyApp(wx.App): def OnInit(self): self.res = xrc.XmlResource('hoge.xrc') self.init_frame() return True def init_frame(self): self.frame = self.res.LoadFrame(None, 'myframe') self.panel = xrc.XRCCTRL(self.frame, 'mypanel') self.frame.Bind(wx.EVT_BUTTON, self.OnMyButton, id=xrc.XRCID('mybutton')) # wx.EVT_BUTTON(self, xrc.XRCID('mybutton'), self.OnMyButton) # also acceptable ?! self.frame.Show() def OnMyButton(self, evt): wx.MessageBox('hoge', 'fuga') if __name__ == '__main__': app = MyApp(False) app.MainLoop()
ChangeLog INDEX