S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
なんちゃってwin32api(あるいはMFC)環境であるpywin32でビットマップを扱う際、意外と手間取ったのでメモ。
やりたかったことは、キャプチャしたビデオ信号のリアルタイム表示。つまり頻繁にやってくるビットマップのデータ列を頻繁に描画したいという状況。Windowsでのビットマップの描画方法は、私の理解では、多分、(有効な)ビットマップハンドルの取得方法に帰着する。なのでデータ列からビットマップハンドルを如何に作るかがここでのお題となる。今のところ、ctypesでCreateDIBSectionを呼出すのが良いと思っており、実際問題なく動作している。
win32gui.LoadImage や PyCBitmap.LoadBitmapFile は単純で簡単だが、リアルタイム表示においていちいちファイルを介するのは速度的に論外。StringIOでメモリ上にファイルオブジェクトを作成すれば速度の問題は解決するかと思い PyCBitmap.LoadBitmapFile でやってみたが、しばらくすると「このコマンドを実行する記憶域がありません」と例外が飛んでくるので、この方法も無理。
そもそもこんな状況ではwin32apiのCreateDIBSectionの使用が定石のひとつと思うが、残念なことにpywin32にこれは定義されていない。(Windows のデバイスコンテキストをビットマップファイルに変換する。Python でも参照)なのでctypesを介してこれを呼出すことにした。
とはいえ私はctypesの動作を深く理解していない(なので下記にいちいちメモをする)。そこでpygletのソースから該当部分を拝借する方法をとった。
CreateDIBSectionにはBITMAPINFOHEADERを渡す必要がある。これを定義するには如何のようにする(window/win32/types.py より)。
from ctypes import * from ctypes.wintypes import * class BITMAPINFOHEADER(Structure): _fields_ = [ ('biSize', DWORD), ('biWidth', LONG), ('biHeight', LONG), ('biPlanes', WORD), ('biBitCount', WORD), ('biCompression', DWORD), ('biSizeImage', DWORD), ('biXPelsPerMeter', LONG), ('biYPelsPerMeter', LONG), ('biClrUsed', DWORD), ('biClrImportant', DWORD), ]
def GetBitmapInfoHeader(w, h): header = BITMAPINFOHEADER() header.biSize = sizeof(header) header.biWidth = w header.biHeight = h header.biPlanes = 1 header.biBitCount = 24 header.biCompression = 0 header.biSizeImage = w*h*3 header.biXPelsPerMeter = 0 header.biYPelsPerMeter = 0 header.biClrUsed = 0 header.biClrImportant = 0 return header
dataptr = c_void_p() bitmap = windll.gdi32.CreateDIBSection(self.GetDC().GetHandleOutput(), byref(GetBitmapInfoHeader(w, h)), win32con.DIB_RGB_COLORS, byref(dataptr), None, 0)
memmove(dataptr, buf, len(buf))
GDIオブジェクト、デバイスコンテキスト、メモリデバイスコンテキストといった単語は作業中はなんとなく解ったつもりでいるが、少し間をおくと木端微塵に忘れる。pywin32で描画のコードを書こうとしたが、やっぱりすっかり忘れていて参った。動いたコードをメモしておく。
from pywin.mfc import dialog import win32con, win32ui class Mydialog(dialog.Dialog): dlgstyle = (win32con.WS_DLGFRAME | win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU ) tmpl = [ ["my dialog", (0, 0, 200, 100), dlgstyle], ] def __init__(self): dialog.Dialog.__init__(self, self.tmpl) def OnPaint(self): dc = self.GetDC() # copy itself dc.BitBlt((0,0), (20,20), self.GetWindowDC(), (0,0), win32con.SRCCOPY) # line dc.LineTo((30,30)) # line with a customized pen cpen = win32ui.CreatePen(win32con.PS_SOLID, 5, 10000000) dc.SelectObject(cpen) dc.LineTo((50,50)) # drawing on memory device context dcmem = dc.CreateCompatibleDC() cbmp = win32ui.CreateBitmap() cbmp.CreateCompatibleBitmap(dc, 100, 100) dcmem.SelectObject(cbmp) dcmem.SelectObject(cpen) dcmem.LineTo((30,30)) dc.BitBlt((50,0), (50,50), dcmem, (0,0), win32con.SRCCOPY) self._obj_.OnPaint() d = Mydialog() d.DoModal()
[2008-05-23-1]のVideoCaptureのソースをビルドした際のメモ。
WinXP MCE SP2, VS 2003, PFSDK(Windows Server 2003 SP1 SDK)
プロジェクトを開こうとすると古いとか言われたが、指示通り問題なく新しいプロジェクトに変換できた。
C/C++=>全般=>追加のインクルードディレクトリに追加:
C:\Program Files\Microsoft Platform SDK\Samples\Multimedia\DirectShow\BaseClasses
リンカ=>入力=>追加の依存ファイル で、strmbase.libの場所を変更:
上記BaseClassesディレクトリで nmake /f makefile NODEBUG=hoge としてビルド(hogeはたぶん何でもいい)しstrmbase.libを作った上で
"C:\Program Files\Microsoft Platform SDK\Samples\Multimedia\DirectShow\BaseClasses\WIN2000_RETAIL\strmbase.lib"
に変える。
以上でビルドは通る。
関数を増やしたい場合は元ソースの記述をマネして本体を記述し、Dev_methods 変数にそれを加え、VideoCapture.py も適宜変更する。
試しに、getbuffer関数をそっくりコピペしてgetbuffer2と名前を変え、返り値を下記のように変えDev_methodsとVideoCapture.pyを適宜してやってみたが、ちゃんとBITMAPINFOHEADERがpythonから取得できた。(できたvidcap.pydのサイズが配布物(20KB)より小さい(13KB)のはなぜ?)
PyObject *pbmituple; BITMAPINFOHEADER a = pVideoHeader->bmiHeader; pbmituple = Py_BuildValue("(k, l,l, H,H, k,k, l,l, k,k)", a.biSize, a.biWidth, a.biHeight, a.biPlanes, a.biBitCount, a.biCompression, a.biSizeImage, a.biXPelsPerMeter, a.biYPelsPerMeter, a.biClrUsed, a.biClrImportant); PyObject *value; value = Py_BuildValue("(s#,O)", buffer, size, pbmituple);
[2008-06-09-01]の続き。
vpythonでlabelを隠すためのパッチを作成した。depthtestフラグによって隠す/隠さないを制御できるようにした。パッチは結構強引で、多分作成者の設計指針をないがしろにしており、そのへんが後ろめたい。まあ個人的な使用だからいいや。
I have written a patch of vpython in order to obscure/hide labels when they go behind objects. The behavior can be toggled through "depthtest" flag. Though this ad hoc patch might not meet with the developers design, some might feel confortable in their private usage.
environment:
- Windows MCE XP2, python 2.5.2
- developement softwares as described in VCBuild.txt
- CVS-HEAD source of vpython 4 beta retrieved at 8 Jun '08 (boost_1_35_0.zip should be decompressed in the "dependencies" directories, since "cvisual.sln" assumes that, not boost_1_34_1.zip)
command-line: (in "vpython-core2" directory where "include" and "src" (and others) directories exist)
patch -p1 < patch_file_shown_below.patch
diff -ur original/include/label.hpp modified/include/label.hpp --- original/include/label.hpp Wed Apr 9 06:42:02 2008 +++ modified/include/label.hpp Wed Jun 11 20:12:15 2008 @@ -59,6 +59,9 @@ void set_yoffset( double yoffset); double get_yoffset(); + void set_depthtest( bool _depthtest); + bool get_depthtest(); + void set_border( double border); double get_border(); @@ -85,6 +88,7 @@ // In pixels: double xoffset; // offset from pos + space to the box double yoffset; + bool depthtest; double border; // space between text and box /// A common name for the font. diff -ur original/include/util/displaylist.hpp modified/include/util/displaylist.hpp --- original/include/util/displaylist.hpp Sun Apr 6 10:11:52 2008 +++ modified/include/util/displaylist.hpp Fri Jun 13 16:21:54 2008 @@ -18,6 +18,9 @@ shared_ptr<class displaylist_impl> impl; public: + bool depthtest; + displaylist() : depthtest(true) {} + /** Begin compiling a new displaylist. Nothing is drawn to the screen when rendering commands into the displaylist. Be sure to call gl_compile_end() when you are done. diff -ur original/src/core/display_kernel.cpp modified/src/core/display_kernel.cpp --- original/src/core/display_kernel.cpp Wed Apr 9 12:46:36 2008 +++ modified/src/core/display_kernel.cpp Fri Jun 13 15:37:12 2008 @@ -700,13 +700,15 @@ // Render all objects in screen space. disable_lights(); - gl_disable depth_test( GL_DEPTH_TEST); +// gl_disable depth_test( GL_DEPTH_TEST); typedef std::multimap<vector, displaylist, z_comparator>::iterator screen_iterator; screen_iterator k( scene_geometry.screen_objects.begin()); screen_iterator k_end( scene_geometry.screen_objects.end()); while ( k != k_end) { + if(!k->second.depthtest) glDisable( GL_DEPTH_TEST); k->second.gl_render(); + if(!k->second.depthtest) glEnable( GL_DEPTH_TEST); ++k; } scene_geometry.screen_objects.clear(); diff -ur original/src/core/label.cpp modified/src/core/label.cpp --- original/src/core/label.cpp Tue Apr 15 05:49:58 2008 +++ modified/src/core/label.cpp Wed Jun 11 20:12:15 2008 @@ -20,6 +20,7 @@ space(0), xoffset(0), yoffset(0), + depthtest(false), border(5), font_description(), // also tried "sans", which seems equivalent font_size(-1), // also tried 10, which seems equivalent @@ -37,6 +38,7 @@ space( other.space), xoffset( other.xoffset), yoffset( other.yoffset), + depthtest(other.depthtest), border( other.border), font_description( other.font_description), font_size( other.font_size), @@ -211,6 +213,18 @@ return yoffset; } +void +label::set_depthtest( bool _depthtest) +{ + depthtest = _depthtest; +} + +bool +label::get_depthtest() +{ + return depthtest; +} + void label::set_border( double n_border) { @@ -398,6 +412,7 @@ text_layout->gl_render(scene, text_pos); } glMatrixMode( GL_MODELVIEW); } // Pops the matricies back off the stack list.gl_compile_end(); + list.depthtest = depthtest; check_gl_error(); scene.screen_objects.insert( std::make_pair(pos, list)); } diff -ur original/src/python/wrap_primitive.cpp modified/src/python/wrap_primitive.cpp --- original/src/python/wrap_primitive.cpp Wed Apr 9 03:28:00 2008 +++ modified/src/python/wrap_primitive.cpp Wed Jun 11 20:12:15 2008 @@ -225,6 +225,7 @@ .add_property( "height", &label::get_font_size, &label::set_font_size) .add_property( "xoffset", &label::get_xoffset, &label::set_xoffset) .add_property( "yoffset", &label::get_yoffset, &label::set_yoffset) + .add_property( "depthtest", &label::get_depthtest, &label::set_depthtest) .add_property( "border", &label::get_border, &label::set_border) .add_property( "box", &label::has_box, &label::render_box) .add_property( "line", &label::has_line, &label::render_line)example:
from visual import * box(axis=(1,0,0), length=0.1, height=4, width=4, up=(1,0,0)) cylinder(pos=(-1,0,0), axis=(2,0,0), radius=0.1) ## default behavior #foo = label(pos=( 1.3,0,0), text='foo') #bar = label(pos=(-1.3,0,0), text='bar') # new behavior foo = label(pos=( 1.3,0,0), text='foo', depthtest=True) bar = label(pos=(-1.3,0,0), text='bar', depthtest=True)
imgタグではsrcにURLを指定できるので、各地に離散する画像リソースを1つのHTMLファイルでまとめて表示できる。
同様なことが、CGIの実行結果やHTML出力に対してもできないか?と思い調べた。
できるようである。
IFRAME を使わない方法の補足
iframeかobjectタグを使えばできる。
前者は(X)HTML的には原則使わないべきタグなので、後者の使用が望ましそう。
後者にはIEでうまく表示できないという認識があるようだが、width及びheight属性の指定によりIEでもちゃんと表示できることを上記「IFRAME を使わない方法の補足」から学んだ。
というわけで実際には以下のように記述すれば良いのだろう。
<object data="hoge.py?msg=fuga" type="text/plain" width="200" height="200"> here an object tag exists </object>Firefox2.0.0.14とIE6で、hoge.pyなるCGIの表示を確認できた。 w3m/0.5.1では代替文字列"here an object tag exists"が表示された。
[2008-06-07]でPyWinのMFC(GUI)プログラミングが有望っぽい事をメモした。
さてGUIプログラミングではコントロールの配置がキモである。ソース内にベタ書きするのは、ファイルが1つで済むので好きだけど、ある程度の規模に膨れるとそうも言ってられなくなる。Visual Studioによるwin32/MFC開発ではリソースエディタでもってコントロールの配置を行い、それをリソーススクリプトに保存するが、これが中々具合が良い。これをPyWin32にも活用できないものだろうか?
ResEditなるものがあるようだ。ちょっと導入してみたけど中々良い。リソースの作成はこれで大丈夫そう。(Visual Studioが使えない時という意味で)
では如何にそれをpythonに喰わせるか?という話になる。[Spambayes-checkins] spambayes/Outlook2000/dialogs/resources rcparser.py, NONE, 1.1.2.1 にそれっぽいコードがある。今度試してみよう。
vpythonなるものがある。超簡単に3Dグラフィックを描画できる優れもの。
文字を表示するlabelなるオブジェクトがあるが、これは他のオブジェクトの背後に回っても描画される(つまり常に見えている状態)。あくまで個人的にだが、この振舞はあんまり有難くないと感じる:背後に位置するものはキッチリと隠れてほしい(今後そう思わぬ状況にも遭遇するだろうが、現在はそう思っている)。同様の意見の方もちらほらいる。だけど同等の機能は現行のベータにも備わっていない模様。
vpython is great, while I prefere labels that become hidden when some objects come in front of them.
fixed strings/notes, and hidden labels
[Visualpython-users] label behavior
なんで、自力で何とかすべくCVSのHEADのソースを取ってきていじった。うまくいった様なので顛末をメモしておく。
The "diff" shown below based on CVS-HEAD source succeeded (at least as far as I see) to obscure(hide) labels by objects in front of them. / By adopting a patch shown below to CVS-HEAD source, labels became hidden from view when they went behind objects.
My environment: python 2.5.2 on Windows 2000
結論: display_kernel.cpp 中 display_kernel::draw 内 "Render all objects in screen space" とコメントされてる部分の gl_disable depth_test( GL_DEPTH_TEST); をコメントアウト
以下やったことの冗長な記述。
Windowsにおけるビルド手順はView of /vpython-core2/VCBuild/VCBuild.txtにて丁寧に解説されている。私は記述の通りやったに過ぎない。
まず VPython-Win-Py2.5-4.beta26.exe をSourceForgeから入手しインストールする。必要なものを後に入れ替えるという手順をとっている。大前提として、これがちゃんと動作することを確認しておく。
次にCVSでソースを入手する。以下でできた。パスワードはカラ。(私はCVSの使用は初めてで、オプションの意味と意義は理解していない。CvsGuiのページでダウンロードしたファイルに入ってたcvsntを用いた)
cvs.exe -d :pserver:anonymous@visualpython.cvs.sourceforge.net:/cvsroot/visualpython login cvs.exe -d :pserver:anonymous@visualpython.cvs.sourceforge.net:/cvsroot/visualpython co vpython-core2
安定版及び開発版(のベータリリース)のソースのtar ballがSourceForgeから入手できるが、これらのビルドは私の実力不足により失敗に終わった。
安定版について:配布バイナリは3.2.11だがtar ballで配布されているのは3.2.9のみ。ビルド方法は内包のINSTALL.TXTに詳細に説明されているが、MinGW/MSYSの環境構築が必要で結構面倒。numpyをインストールしろみたいな指示が出たけど実際に必要なのはNumericかnumarrayな感じだったり、またビルドしてはみたもののよくわからんImportErrorが出たり、手当たり次第に.pthを作るも状況は改善しないなどしたため、理解があやふやなまま断念することにした。3.2.9はpython2.4の使用を念頭に置いており、3.2.10でpython2.5使用に切り替えたようなので、この辺が関係あるのかも?いずれにせよ気力は尽きた。
開発版について:beta26を試した。MSWINDOWS.txtにまたまた詳細なビルド手順が記されているが、一層面倒なMinGW/MSYSとGTKの環境構築を含み(私見だが)苦行のように長い。頑張ってみたものの、一旦つまずいた所で気力が尽きてやめた。
CVSで入手したソースには必要なboostも付属するしVisual Studioのソリューションを開いてビルドすれば終わるという手軽で幸せな方法が用意されている。同梱の MSWINDOWS.txt にもその旨記載されていた。
入手したソースで dependencies の中にboostが用意されている。boost_1_34_1 なる展開済のディレクトリはできていたが、同梱のVisual Studioのソリューションでは boost_1_35_0 を使う設定になっていた。ソリューションの設定を修正してもいいのかもしれないが、幸い boost_1_35_0.zip は同梱されていたので、これを展開して使うことにした。
そしてビルド環境を整える。Visual C++ 2005 Express Edition と platform SDK を導入すれば良い。前者をVisual Studio Developer CenterのDownloadから導入した(Version 8.0.50727.42 だった)。platform SDKは既に導入済だった。確か http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en から入手したはず。スタートメニューでの表記は"Microsoft Platform SDK for Windows Server 2003 SP1"だった。幾つか細かな設定が必要だがVCBuild.txtに従って行った。
まずソースを修正せずにビルドしたもので動作確認をした。C:\Python25\Lib\site-packages\visual をゴッソリ消して、VCBuild.txtの指示通りにCVSで拾ってきたものと入れ替えた。入れ替え後のものにはgtk関連のDLLがあらかた抜けてた。そしてVS上でビルドする。成果物は多分 cvisual.pyd だけなのだろうが、これは自動的にあるべき場所に配置される。(VS上で Project => Property => Configuration Properties => Linker => General => Output File を見よ)なので、ビルド後に適当なスクリプトが動作すれば、ビルドには成功している。(気持ち、動きがスムーズになったと感じた)
いよいよソース修正。上述したように、一箇所のコメントアウトでできているみたい。display_kernel.cpp 中 display_kernel::draw 内 "Render all objects in screen space" とコメントされてる部分の gl_disable depth_test( GL_DEPTH_TEST); をコメントアウトする。OpenGLの事は全くわからないが、この行が前後関係を司っているらしい。
$ diff -u display_kernel.cpp.orig display_kernel.cpp --- display_kernel.cpp.orig Wed Apr 9 12:46:36 2008 +++ display_kernel.cpp Sun Jun 8 21:30:02 2008 @@ -700,7 +700,7 @@ // Render all objects in screen space. disable_lights(); - gl_disable depth_test( GL_DEPTH_TEST); +// gl_disable depth_test( GL_DEPTH_TEST); typedef std::multimap<vector, displaylist, z_comparator>::iterator screen_iterator; screen_iterator k( scene_geometry.screen_objects.begin());
pywin32のmfcラッパを試している。pythonで結構簡単にWindowsのダイアログが作れて、良さそう。
とりあえず手元で試して動いたコードをメモ。
とにかくダイアログを出す、という例が以下。拡張子をpywにして保存しダブルクリックすればOK。
from pywin.mfc import dialog import win32con class Mydialog(dialog.Dialog): dlgstyle = (win32con.WS_DLGFRAME | win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU ) btnstyle = (win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP | win32con.WS_CHILD | win32con.WS_VISIBLE) dlgButton = 0x0080 tmpl = [ ["my dialog", (0, 0, 200, 100), dlgstyle], # dialog [dlgButton, "my OK", win32con.IDOK, (5, 55, 190, 40), btnstyle], # button ] def __init__(self): dialog.Dialog.__init__(self, self.tmpl) d = Mydialog() d.DoModal()
from pywin.mfc import dialog import win32con class Mydialog(dialog.Dialog): dlgstyle = (win32con.WS_MINIMIZEBOX | win32con.WS_DLGFRAME | win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU | win32con.DS_SETFONT ) btnstyle = (win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP | win32con.WS_CHILD | win32con.WS_VISIBLE) IDC_MYBUTTON = 1025 dlgButton = 0x0080 tmpl = [ ["my dialog", (0, 0, 200, 100), dlgstyle], # dialog [dlgButton, "my OK", win32con.IDOK, (5, 5, 190, 40), btnstyle], # button [dlgButton, "my button", IDC_MYBUTTON, (5, 55, 190, 40), btnstyle], # button ] def __init__(self): dialog.Dialog.__init__(self, self.tmpl) def OnInitDialog(self): rc = dialog.Dialog.OnInitDialog(self) self.HookCommand(self.OnMyButton, self.IDC_MYBUTTON) self.btn = self.GetDlgItem(self.IDC_MYBUTTON) return rc def OnMyButton(self, id, cmd): if cmd==win32con.BN_CLICKED: ret = self.MessageBox('hello, my button', 'my caption', win32con.MB_YESNO) if ret==win32con.IDYES: cap = 'yes' else: cap = 'no' self.btn.SetWindowText(cap) def OnOK(self): rc = dialog.Dialog.OnOK(self) self.MessageBox('OnOK!', 'farewell') return rc def OnCancel(self): rc = dialog.Dialog.OnCancel(self) self.MessageBox('OnCancel!', 'farewell') return rc d = Mydialog() d.DoModal()
self.btn = win32ui.CreateButton() self.btn.CreateWindow('my button', self.btnstyle, (10, 75, 340, 140), self, self.IDC_MYBUTTON)
from pywin.mfc import dialog import win32con class Mydialog(dialog.Dialog): dlgstyle = (win32con.WS_MINIMIZEBOX | win32con.WS_DLGFRAME | win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU | win32con.DS_SETFONT ) btnstyle = (win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP | win32con.WS_CHILD | win32con.WS_VISIBLE) staticstyle = (win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.SS_LEFT) IDC_MYBUTTON = 1025 IDC_MYSTATIC = 1026 dlgButton = 0x0080 dlgStatic = 0x0082 tmpl = [ ["my dialog", (0, 0, 200, 130), dlgstyle, None, (14,'Arial')], # dialog [dlgButton, "my OK", win32con.IDOK, (5, 5, 190, 40), btnstyle], # button [dlgButton, "my button", IDC_MYBUTTON, (5, 55, 190, 40), btnstyle], # button [dlgStatic, "my static", IDC_MYSTATIC, (5,105, 190, 20), staticstyle], # static ] timerid = 1 def __init__(self): dialog.Dialog.__init__(self, self.tmpl) def OnInitDialog(self): rc = dialog.Dialog.OnInitDialog(self) self.HookCommand(self.OnMyButton, self.IDC_MYBUTTON) self.static = self.GetDlgItem(self.IDC_MYSTATIC) self.timerflag = False self.timercount = 0 return rc def OnMyButton(self, id, cmd): if cmd==win32con.BN_CLICKED: if self.timerflag: self.KillTimer(self.timerid) else: self.SetTimer(self.timerid, 500) # 0.5s self.timerflag = not self.timerflag def OnTimer(self, nIDEvent): self.timercount += 1 self.static.SetWindowText('timer! %d' % self.timercount) def OnOK(self): rc = dialog.Dialog.OnOK(self) self.MessageBox('OnOK!', 'farewell') return rc def OnCancel(self): rc = dialog.Dialog.OnCancel(self) self.MessageBox('OnCancel!', 'farewell') return rc d = Mydialog() d.DoModal()
imgタグではsrcにURLを指定できるので、各地に離散する画像リソースを1つのHTMLファイルでまとめて表示できる。
同様なことが、CGIの実行結果やHTML出力に対してもできないか?と思い調べた。
できるようである。
IFRAME を使わない方法の補足
iframeかobjectタグを使えばできる。
前者は(X)HTML的には原則使わないべきタグなので、後者の使用が望ましそう。
後者にはIEでうまく表示できないという認識があるようだが、width及びheight属性の指定によりIEでもちゃんと表示できることを上記「IFRAME を使わない方法の補足」から学んだ。
というわけで実際には以下のように記述すれば良いのだろう。
<object data="hoge.py?msg=fuga" type="text/plain" width="200" height="200"> here an object tag exists </object>Firefox2.0.0.14とIE6で、hoge.pyなるCGIの表示を確認できた。 w3m/0.5.1では代替文字列"here an object tag exists"が表示された。
pythonでCOMを使うためPython for Windows extensions (see also: Mark Hammond's Free Stuff)を導入した。他の機能にも触れてみようとしている。mfcまわりもラップされているのでGUIアプリケーションも書けるようだ。windowsに特化するなら、MFCへの慣れを勘案すれば、wxPythonよりこっちを使う方がラクかな?
とりあえず簡易な入力ダイアログが非常に簡単に作成できるようなのでメモ。後々重宝しそうな気がする。
import pywin.mfc.dialog print pywin.mfc.dialog.GetSimpleInput("my textbox title", 'my default value', 'my window title')
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
最終更新時間: 2010-03-08 22:21