Hatena::ブログ(Diary)

sirocco の書いてもすぐに忘れるメモ

2014-07-26

Python: wxFormbuilder を使ってwxPythonアプリを作る。

| 12:48 |

PythonwxPythonGUIビルダwxFormBuilderを使って、テストアプリを作ってみました。

【環境】

f:id:sirocco:20140726124553j:image

「OK」ボタンを押すとテキストボックスに「OK」の文字が追加され、「CLEAR」ボタンを押すとテキストボックスをクリアします。

wxHaskellのときはXRCファイルを読み込んで、イベントは自分で設定していましたが、今回はwxFormbuilderでイベントを設定しました。

  • イベントの設定方法
    • Designerの「OK」のボタンを選択->EventのOnButtonClick欄に「OnButtunOK」。
    • Designerの「CLEAR」のボタンを選択->EventのOnButtonClick欄に「OnButtunCLEAR」。
  • wxTest.fbp : wxFormbuilder 自身の保存ファイル
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
    <FileVersion major="1" minor="11" />
    <object class="Project" expanded="1">
        <property name="class_decoration"></property>
        <property name="code_generation">Python</property>
        <property name="disconnect_events">1</property>
        <property name="disconnect_mode">source_name</property>
        <property name="disconnect_php_events">0</property>
        <property name="disconnect_python_events">0</property>
        <property name="embedded_files_path">res</property>
        <property name="encoding">UTF-8</property>
        <property name="event_generation">connect</property>
        <property name="file">pytest</property>
        <property name="first_id">1000</property>
        <property name="help_provider">none</property>
        <property name="internationalize">0</property>
        <property name="name">pytest</property>
        <property name="namespace"></property>
        <property name="path">.</property>
        <property name="precompiled_header"></property>
        <property name="relative_path">1</property>
        <property name="skip_lua_events">1</property>
        <property name="skip_php_events">1</property>
        <property name="skip_python_events">1</property>
        <property name="ui_table">UI</property>
        <property name="use_enum">0</property>
        <property name="use_microsoft_bom">0</property>
        <object class="Frame" expanded="1">
            <property name="aui_managed">0</property>
            <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
            <property name="bg"></property>
            <property name="center">wxBOTH</property>
            <property name="context_help"></property>
            <property name="context_menu">1</property>
            <property name="enabled">1</property>
            <property name="event_handler">impl_virtual</property>
            <property name="extra_style"></property>
            <property name="fg"></property>
            <property name="font"></property>
            <property name="hidden">0</property>
            <property name="id">wxID_ANY</property>
            <property name="maximum_size"></property>
            <property name="minimum_size"></property>
            <property name="name">fMain</property>
            <property name="pos"></property>
            <property name="size">500,300</property>
            <property name="style">wxDEFAULT_FRAME_STYLE</property>
            <property name="subclass"></property>
            <property name="title">wxFormbuilder TEST</property>
            <property name="tooltip"></property>
            <property name="window_extra_style"></property>
            <property name="window_name"></property>
            <property name="window_style">wxTAB_TRAVERSAL</property>
            <property name="xrc_skip_sizer">1</property>
            <event name="OnActivate"></event>
            <event name="OnActivateApp"></event>
            <event name="OnAuiFindManager"></event>
            <event name="OnAuiPaneButton"></event>
            <event name="OnAuiPaneClose"></event>
            <event name="OnAuiPaneMaximize"></event>
            <event name="OnAuiPaneRestore"></event>
            <event name="OnAuiRender"></event>
            <event name="OnChar"></event>
            <event name="OnClose"></event>
            <event name="OnEnterWindow"></event>
            <event name="OnEraseBackground"></event>
            <event name="OnHibernate"></event>
            <event name="OnIconize"></event>
            <event name="OnIdle"></event>
            <event name="OnKeyDown"></event>
            <event name="OnKeyUp"></event>
            <event name="OnKillFocus"></event>
            <event name="OnLeaveWindow"></event>
            <event name="OnLeftDClick"></event>
            <event name="OnLeftDown"></event>
            <event name="OnLeftUp"></event>
            <event name="OnMiddleDClick"></event>
            <event name="OnMiddleDown"></event>
            <event name="OnMiddleUp"></event>
            <event name="OnMotion"></event>
            <event name="OnMouseEvents"></event>
            <event name="OnMouseWheel"></event>
            <event name="OnPaint"></event>
            <event name="OnRightDClick"></event>
            <event name="OnRightDown"></event>
            <event name="OnRightUp"></event>
            <event name="OnSetFocus"></event>
            <event name="OnSize"></event>
            <event name="OnUpdateUI"></event>
            <object class="wxBoxSizer" expanded="1">
                <property name="minimum_size"></property>
                <property name="name">bSizer1</property>
                <property name="orient">wxVERTICAL</property>
                <property name="permission">none</property>
                <object class="sizeritem" expanded="1">
                    <property name="border">5</property>
                    <property name="flag">wxEXPAND</property>
                    <property name="proportion">1</property>
                    <object class="wxPanel" expanded="1">
                        <property name="BottomDockable">1</property>
                        <property name="LeftDockable">1</property>
                        <property name="RightDockable">1</property>
                        <property name="TopDockable">1</property>
                        <property name="aui_layer"></property>
                        <property name="aui_name"></property>
                        <property name="aui_position"></property>
                        <property name="aui_row"></property>
                        <property name="best_size"></property>
                        <property name="bg"></property>
                        <property name="caption"></property>
                        <property name="caption_visible">1</property>
                        <property name="center_pane">0</property>
                        <property name="close_button">1</property>
                        <property name="context_help"></property>
                        <property name="context_menu">1</property>
                        <property name="default_pane">0</property>
                        <property name="dock">Dock</property>
                        <property name="dock_fixed">0</property>
                        <property name="docking">Left</property>
                        <property name="enabled">1</property>
                        <property name="fg"></property>
                        <property name="floatable">1</property>
                        <property name="font"></property>
                        <property name="gripper">0</property>
                        <property name="hidden">0</property>
                        <property name="id">wxID_ANY</property>
                        <property name="max_size"></property>
                        <property name="maximize_button">0</property>
                        <property name="maximum_size"></property>
                        <property name="min_size"></property>
                        <property name="minimize_button">0</property>
                        <property name="minimum_size"></property>
                        <property name="moveable">1</property>
                        <property name="name">m_panel1</property>
                        <property name="pane_border">1</property>
                        <property name="pane_position"></property>
                        <property name="pane_size"></property>
                        <property name="permission">protected</property>
                        <property name="pin_button">1</property>
                        <property name="pos"></property>
                        <property name="resize">Resizable</property>
                        <property name="show">1</property>
                        <property name="size"></property>
                        <property name="subclass"></property>
                        <property name="toolbar_pane">0</property>
                        <property name="tooltip"></property>
                        <property name="window_extra_style"></property>
                        <property name="window_name"></property>
                        <property name="window_style">wxTAB_TRAVERSAL</property>
                        <event name="OnChar"></event>
                        <event name="OnEnterWindow"></event>
                        <event name="OnEraseBackground"></event>
                        <event name="OnKeyDown"></event>
                        <event name="OnKeyUp"></event>
                        <event name="OnKillFocus"></event>
                        <event name="OnLeaveWindow"></event>
                        <event name="OnLeftDClick"></event>
                        <event name="OnLeftDown"></event>
                        <event name="OnLeftUp"></event>
                        <event name="OnMiddleDClick"></event>
                        <event name="OnMiddleDown"></event>
                        <event name="OnMiddleUp"></event>
                        <event name="OnMotion"></event>
                        <event name="OnMouseEvents"></event>
                        <event name="OnMouseWheel"></event>
                        <event name="OnPaint"></event>
                        <event name="OnRightDClick"></event>
                        <event name="OnRightDown"></event>
                        <event name="OnRightUp"></event>
                        <event name="OnSetFocus"></event>
                        <event name="OnSize"></event>
                        <event name="OnUpdateUI"></event>
                        <object class="wxBoxSizer" expanded="1">
                            <property name="minimum_size"></property>
                            <property name="name">bSizer2</property>
                            <property name="orient">wxVERTICAL</property>
                            <property name="permission">none</property>
                            <object class="sizeritem" expanded="1">
                                <property name="border">5</property>
                                <property name="flag">wxALL|wxEXPAND</property>
                                <property name="proportion">1</property>
                                <object class="wxTextCtrl" expanded="1">
                                    <property name="BottomDockable">1</property>
                                    <property name="LeftDockable">1</property>
                                    <property name="RightDockable">1</property>
                                    <property name="TopDockable">1</property>
                                    <property name="aui_layer"></property>
                                    <property name="aui_name"></property>
                                    <property name="aui_position"></property>
                                    <property name="aui_row"></property>
                                    <property name="best_size"></property>
                                    <property name="bg"></property>
                                    <property name="caption"></property>
                                    <property name="caption_visible">1</property>
                                    <property name="center_pane">0</property>
                                    <property name="close_button">1</property>
                                    <property name="context_help"></property>
                                    <property name="context_menu">1</property>
                                    <property name="default_pane">0</property>
                                    <property name="dock">Dock</property>
                                    <property name="dock_fixed">0</property>
                                    <property name="docking">Left</property>
                                    <property name="enabled">1</property>
                                    <property name="fg"></property>
                                    <property name="floatable">1</property>
                                    <property name="font"></property>
                                    <property name="gripper">0</property>
                                    <property name="hidden">0</property>
                                    <property name="id">wxID_ANY</property>
                                    <property name="max_size"></property>
                                    <property name="maximize_button">0</property>
                                    <property name="maximum_size"></property>
                                    <property name="maxlength"></property>
                                    <property name="min_size"></property>
                                    <property name="minimize_button">0</property>
                                    <property name="minimum_size"></property>
                                    <property name="moveable">1</property>
                                    <property name="name">m_textCtrl1</property>
                                    <property name="pane_border">1</property>
                                    <property name="pane_position"></property>
                                    <property name="pane_size"></property>
                                    <property name="permission">protected</property>
                                    <property name="pin_button">1</property>
                                    <property name="pos"></property>
                                    <property name="resize">Resizable</property>
                                    <property name="show">1</property>
                                    <property name="size"></property>
                                    <property name="style"></property>
                                    <property name="subclass"></property>
                                    <property name="toolbar_pane">0</property>
                                    <property name="tooltip"></property>
                                    <property name="validator_data_type"></property>
                                    <property name="validator_style">wxFILTER_NONE</property>
                                    <property name="validator_type">wxDefaultValidator</property>
                                    <property name="validator_variable"></property>
                                    <property name="value"></property>
                                    <property name="window_extra_style"></property>
                                    <property name="window_name"></property>
                                    <property name="window_style"></property>
                                    <event name="OnChar"></event>
                                    <event name="OnEnterWindow"></event>
                                    <event name="OnEraseBackground"></event>
                                    <event name="OnKeyDown"></event>
                                    <event name="OnKeyUp"></event>
                                    <event name="OnKillFocus"></event>
                                    <event name="OnLeaveWindow"></event>
                                    <event name="OnLeftDClick"></event>
                                    <event name="OnLeftDown"></event>
                                    <event name="OnLeftUp"></event>
                                    <event name="OnMiddleDClick"></event>
                                    <event name="OnMiddleDown"></event>
                                    <event name="OnMiddleUp"></event>
                                    <event name="OnMotion"></event>
                                    <event name="OnMouseEvents"></event>
                                    <event name="OnMouseWheel"></event>
                                    <event name="OnPaint"></event>
                                    <event name="OnRightDClick"></event>
                                    <event name="OnRightDown"></event>
                                    <event name="OnRightUp"></event>
                                    <event name="OnSetFocus"></event>
                                    <event name="OnSize"></event>
                                    <event name="OnText"></event>
                                    <event name="OnTextEnter"></event>
                                    <event name="OnTextMaxLen"></event>
                                    <event name="OnTextURL"></event>
                                    <event name="OnUpdateUI"></event>
                                </object>
                            </object>
                            <object class="sizeritem" expanded="1">
                                <property name="border">5</property>
                                <property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
                                <property name="proportion">0</property>
                                <object class="wxBoxSizer" expanded="1">
                                    <property name="minimum_size"></property>
                                    <property name="name">bSizer3</property>
                                    <property name="orient">wxHORIZONTAL</property>
                                    <property name="permission">none</property>
                                    <object class="sizeritem" expanded="1">
                                        <property name="border">5</property>
                                        <property name="flag"></property>
                                        <property name="proportion">0</property>
                                        <object class="wxFlexGridSizer" expanded="1">
                                            <property name="cols">2</property>
                                            <property name="flexible_direction">wxBOTH</property>
                                            <property name="growablecols"></property>
                                            <property name="growablerows"></property>
                                            <property name="hgap">0</property>
                                            <property name="minimum_size"></property>
                                            <property name="name">fgSizer1</property>
                                            <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
                                            <property name="permission">none</property>
                                            <property name="rows">1</property>
                                            <property name="vgap">0</property>
                                            <object class="sizeritem" expanded="1">
                                                <property name="border">5</property>
                                                <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                                                <property name="proportion">0</property>
                                                <object class="wxButton" expanded="1">
                                                    <property name="BottomDockable">1</property>
                                                    <property name="LeftDockable">1</property>
                                                    <property name="RightDockable">1</property>
                                                    <property name="TopDockable">1</property>
                                                    <property name="aui_layer"></property>
                                                    <property name="aui_name"></property>
                                                    <property name="aui_position"></property>
                                                    <property name="aui_row"></property>
                                                    <property name="best_size"></property>
                                                    <property name="bg"></property>
                                                    <property name="caption"></property>
                                                    <property name="caption_visible">1</property>
                                                    <property name="center_pane">0</property>
                                                    <property name="close_button">1</property>
                                                    <property name="context_help"></property>
                                                    <property name="context_menu">1</property>
                                                    <property name="default">0</property>
                                                    <property name="default_pane">0</property>
                                                    <property name="dock">Dock</property>
                                                    <property name="dock_fixed">0</property>
                                                    <property name="docking">Left</property>
                                                    <property name="enabled">1</property>
                                                    <property name="fg"></property>
                                                    <property name="floatable">1</property>
                                                    <property name="font"></property>
                                                    <property name="gripper">0</property>
                                                    <property name="hidden">0</property>
                                                    <property name="id">wxID_ANY</property>
                                                    <property name="label">OK</property>
                                                    <property name="max_size"></property>
                                                    <property name="maximize_button">0</property>
                                                    <property name="maximum_size"></property>
                                                    <property name="min_size"></property>
                                                    <property name="minimize_button">0</property>
                                                    <property name="minimum_size"></property>
                                                    <property name="moveable">1</property>
                                                    <property name="name">m_button1</property>
                                                    <property name="pane_border">1</property>
                                                    <property name="pane_position"></property>
                                                    <property name="pane_size"></property>
                                                    <property name="permission">protected</property>
                                                    <property name="pin_button">1</property>
                                                    <property name="pos"></property>
                                                    <property name="resize">Resizable</property>
                                                    <property name="show">1</property>
                                                    <property name="size"></property>
                                                    <property name="style"></property>
                                                    <property name="subclass"></property>
                                                    <property name="toolbar_pane">0</property>
                                                    <property name="tooltip"></property>
                                                    <property name="validator_data_type"></property>
                                                    <property name="validator_style">wxFILTER_NONE</property>
                                                    <property name="validator_type">wxDefaultValidator</property>
                                                    <property name="validator_variable"></property>
                                                    <property name="window_extra_style"></property>
                                                    <property name="window_name"></property>
                                                    <property name="window_style"></property>
                                                    <event name="OnButtonClick">OnButtunOK</event>
                                                    <event name="OnChar"></event>
                                                    <event name="OnEnterWindow"></event>
                                                    <event name="OnEraseBackground"></event>
                                                    <event name="OnKeyDown"></event>
                                                    <event name="OnKeyUp"></event>
                                                    <event name="OnKillFocus"></event>
                                                    <event name="OnLeaveWindow"></event>
                                                    <event name="OnLeftDClick"></event>
                                                    <event name="OnLeftDown"></event>
                                                    <event name="OnLeftUp"></event>
                                                    <event name="OnMiddleDClick"></event>
                                                    <event name="OnMiddleDown"></event>
                                                    <event name="OnMiddleUp"></event>
                                                    <event name="OnMotion"></event>
                                                    <event name="OnMouseEvents"></event>
                                                    <event name="OnMouseWheel"></event>
                                                    <event name="OnPaint"></event>
                                                    <event name="OnRightDClick"></event>
                                                    <event name="OnRightDown"></event>
                                                    <event name="OnRightUp"></event>
                                                    <event name="OnSetFocus"></event>
                                                    <event name="OnSize"></event>
                                                    <event name="OnUpdateUI"></event>
                                                </object>
                                            </object>
                                            <object class="sizeritem" expanded="1">
                                                <property name="border">5</property>
                                                <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                                                <property name="proportion">0</property>
                                                <object class="wxButton" expanded="1">
                                                    <property name="BottomDockable">1</property>
                                                    <property name="LeftDockable">1</property>
                                                    <property name="RightDockable">1</property>
                                                    <property name="TopDockable">1</property>
                                                    <property name="aui_layer"></property>
                                                    <property name="aui_name"></property>
                                                    <property name="aui_position"></property>
                                                    <property name="aui_row"></property>
                                                    <property name="best_size"></property>
                                                    <property name="bg"></property>
                                                    <property name="caption"></property>
                                                    <property name="caption_visible">1</property>
                                                    <property name="center_pane">0</property>
                                                    <property name="close_button">1</property>
                                                    <property name="context_help"></property>
                                                    <property name="context_menu">1</property>
                                                    <property name="default">0</property>
                                                    <property name="default_pane">0</property>
                                                    <property name="dock">Dock</property>
                                                    <property name="dock_fixed">0</property>
                                                    <property name="docking">Left</property>
                                                    <property name="enabled">1</property>
                                                    <property name="fg"></property>
                                                    <property name="floatable">1</property>
                                                    <property name="font"></property>
                                                    <property name="gripper">0</property>
                                                    <property name="hidden">0</property>
                                                    <property name="id">wxID_ANY</property>
                                                    <property name="label">CLEAR</property>
                                                    <property name="max_size"></property>
                                                    <property name="maximize_button">0</property>
                                                    <property name="maximum_size"></property>
                                                    <property name="min_size"></property>
                                                    <property name="minimize_button">0</property>
                                                    <property name="minimum_size"></property>
                                                    <property name="moveable">1</property>
                                                    <property name="name">m_button2</property>
                                                    <property name="pane_border">1</property>
                                                    <property name="pane_position"></property>
                                                    <property name="pane_size"></property>
                                                    <property name="permission">protected</property>
                                                    <property name="pin_button">1</property>
                                                    <property name="pos"></property>
                                                    <property name="resize">Resizable</property>
                                                    <property name="show">1</property>
                                                    <property name="size"></property>
                                                    <property name="style"></property>
                                                    <property name="subclass"></property>
                                                    <property name="toolbar_pane">0</property>
                                                    <property name="tooltip"></property>
                                                    <property name="validator_data_type"></property>
                                                    <property name="validator_style">wxFILTER_NONE</property>
                                                    <property name="validator_type">wxDefaultValidator</property>
                                                    <property name="validator_variable"></property>
                                                    <property name="window_extra_style"></property>
                                                    <property name="window_name"></property>
                                                    <property name="window_style"></property>
                                                    <event name="OnButtonClick">OnButtunCLEAR</event>
                                                    <event name="OnChar"></event>
                                                    <event name="OnEnterWindow"></event>
                                                    <event name="OnEraseBackground"></event>
                                                    <event name="OnKeyDown"></event>
                                                    <event name="OnKeyUp"></event>
                                                    <event name="OnKillFocus"></event>
                                                    <event name="OnLeaveWindow"></event>
                                                    <event name="OnLeftDClick"></event>
                                                    <event name="OnLeftDown"></event>
                                                    <event name="OnLeftUp"></event>
                                                    <event name="OnMiddleDClick"></event>
                                                    <event name="OnMiddleDown"></event>
                                                    <event name="OnMiddleUp"></event>
                                                    <event name="OnMotion"></event>
                                                    <event name="OnMouseEvents"></event>
                                                    <event name="OnMouseWheel"></event>
                                                    <event name="OnPaint"></event>
                                                    <event name="OnRightDClick"></event>
                                                    <event name="OnRightDown"></event>
                                                    <event name="OnRightUp"></event>
                                                    <event name="OnSetFocus"></event>
                                                    <event name="OnSize"></event>
                                                    <event name="OnUpdateUI"></event>
                                                </object>
                                            </object>
                                        </object>
                                    </object>
                                </object>
                            </object>
                        </object>
                    </object>
                </object>
            </object>
        </object>
    </object>
</wxFormBuilder_Project>
  • pytest.py : F8(File-> Generate Code) でwxFormbuilderが吐き出したファイル

Project の Properties の file で設定した名前になる。設定しないと noname.py

# -*- coding: utf-8 -*- 

###########################################################################
## Python code generated with wxFormBuilder (version May 15 2013)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################

import wx
import wx.xrc

###########################################################################
## Class fMain
###########################################################################

class fMain ( wx.Frame ):
    
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"wxFormbuilder TEST", pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
        
        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
        
        bSizer1 = wx.BoxSizer( wx.VERTICAL )
        
        self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        bSizer2 = wx.BoxSizer( wx.VERTICAL )
        
        self.m_textCtrl1 = wx.TextCtrl( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5 )
        
        bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
        
        fgSizer1 = wx.FlexGridSizer( 1, 2, 0, 0 )
        fgSizer1.SetFlexibleDirection( wx.BOTH )
        fgSizer1.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
        
        self.m_button1 = wx.Button( self.m_panel1, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
        fgSizer1.Add( self.m_button1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
        
        self.m_button2 = wx.Button( self.m_panel1, wx.ID_ANY, u"CLEAR", wx.DefaultPosition, wx.DefaultSize, 0 )
        fgSizer1.Add( self.m_button2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
        
        
        bSizer3.Add( fgSizer1, 0, 0, 5 )
        
        
        bSizer2.Add( bSizer3, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 )
        
        
        self.m_panel1.SetSizer( bSizer2 )
        self.m_panel1.Layout()
        bSizer2.Fit( self.m_panel1 )
        bSizer1.Add( self.m_panel1, 1, wx.EXPAND, 5 )
        
        
        self.SetSizer( bSizer1 )
        self.Layout()
        
        self.Centre( wx.BOTH )
        
        # Connect Events
        # イベントが追加されています。
        self.m_button1.Bind( wx.EVT_BUTTON, self.OnButtunOK )
        self.m_button2.Bind( wx.EVT_BUTTON, self.OnButtunCLEAR )
    
    def __del__( self ):
        pass
    
    
    # Virtual event handlers, overide them in your derived class
    def OnButtunOK( self, event ):
        event.Skip()
    
    def OnButtunCLEAR( self, event ):
        event.Skip()

Tools の「Generate Inherited Class F6」をクリックすると継承ファイルを作ります。

f:id:sirocco:20140726125510j:image

  • pytestfMain.py : 継承してwxFormBuilderが作成したファイル。
"""Subclass of fMain, which is generated by wxFormBuilder."""

import wx
import pytest

# Implementing fMain
class pytestfMain( pytest.fMain ):
    def __init__( self, parent ):
        pytest.fMain.__init__( self, parent )

    # Handlers for fMain events.
    def OnButtunOK( self, event ):
        self.m_textCtrl1.AppendText('OK') # これを書き加えた

    def OnButtunCLEAR( self, event ):
        self.m_textCtrl1.Clear()          # これを書き加えた
  • pytestApp.py : 新たに作ったメイン
import wx
from pytestfMain import pytestfMain as fMain

app = wx.App()
frame = fMain(None)
# アイコンを表示するようにしました。
frame.SetIcon(wx.Icon("wxwin.ico",wx.BITMAP_TYPE_ICO))
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()

wxFormbuilderが吐き出すソースはTABによるインデントなのでスペースでインデントするとエラーになります。テキストエディダの置換でスペースに変換しましょう。

2014-07-25

Python: win32com を使ってDBにADO接続してみる。

| 14:24 |

Python and ActiveX Data Objects (ADO)を参考にMS AccessMDBにアクセスしてみました。

使用しているMDBは「Win32OLE 活用法 【第 3 回】 ADODB」のsample1.mdbです。

# -*- coding: cp932 -*-
import win32com.client
import sys
import codecs

# 参考
# http://www.ecp.cc/pyado.html#1

conn = win32com.client.Dispatch(r'ADODB.Connection')
DSN ='DRIVER={Microsoft Access Driver (*.mdb)};Dbq=C:\\Python27\\test\\COM\\sample1.mdb'

# MS SQL Server のとき
# DSN ='Provider=SQLOLEDB.1;Password=xxxxxxx;User ID=xxxx;Initial Catalog=DBname;Data Source=tcp:192.168.1.123,1433'

conn.Open(DSN)
        
rs = win32com.client.Dispatch(r'ADODB.Recordset')
rs_name = 'earthquake'
strsql = '"SELECT * FROM earthquake;'

rs.Open('[' + rs_name + ']', conn, 1, 3)
# rs.Open(strsql, conn, 1, 3)
        
print rs.RecordCount # => 4

flds_name  = {}
flds_Value = {}
fCount = rs.Fields.Count # フィールド数

for x in range(fCount):
    flds_name[x] = rs.Fields.Item(x).Name

# フィールド名
print flds_name # => {0: u'Name', 1: u'Day', 2: u'Magnitude', 3: u'NumOfDeaths', 4: u'DeadOrAlive'}

rs.MoveFirst()
print type(rs.Fields.Item(0).Value)                   #=> <type 'unicode'>
print type(rs.Fields.Item(0).Value.encode('cp932'))   #=> <type 'str'>
print rs.Fields.Item(0).Value.encode('cp932')         #=> 関東大震災
print rs.Fields.Item(0).Value                         #=> 関東大震災
print rs.Fields.Item(0).Type                          #=> 202
print rs.Fields.Item(0).DefinedSize                   #=> 50

# 全データをtable_Valueに取得する。
rs.MoveFirst()
count = 0
table_Value = {}
while 1:
    if rs.EOF:
        break
    else:
        flds_Value = {}
        for x in range(fCount):
            flds_Value[x] = rs.Fields.Item(x).Value
        table_Value[count] = flds_Value
        count = count + 1
        rs.MoveNext()

print table_Value

# {0: {0: u'\u95a2\u6771\u5927\u9707\u707d', 1: <PyTime:1923/09/01 0:00:00>, 2: 7.9, 3: 142807, 4: u'-1'}, 
#  1: {0: u'\u962a\u795e\u6de1\u8def\u5927\u9707\u707d', 1: <PyTime:1995/01/17 0:00:00>, 2: 7.2, 3: 6418, 4: u'-1'}, 
#  2: {0: u'\u65b0\u6f5f\u770c\u4e2d\u8d8a\u5730\u9707', 1: <PyTime:2004/10/23 0:00:00>, 2: 6.8, 3: 37, 4: u'-1'}, 
#  3: {0: u'\u5317\u6d77\u9053\u6771\u65b9\u6c96\u5730\u9707', 1: <PyTime:1994/10/04 0:00:00>, 2: 8.1, 3: 0, 4: u'0'}}

# フィールドの型を表示してみる。
for x in range(fCount):
    print type(table_Value[0][x])
#=>  <type 'unicode'>
#    <type 'time'>
#    <type 'float'>
#    <type 'int'>
#    <type 'unicode'>


# 全テーブル表示
oCat = win32com.client.Dispatch(r'ADOX.Catalog')
oCat.ActiveConnection = conn
oTab = oCat.Tables
for x in oTab:
     if x.Type == 'TABLE':
         print x.Name  #=> earthquake

rs.Close()
conn.Close()

ConEmuのutf-8環境で文字列出力がエラーになって苦労したのですが、Windows PowerSHell で実行すると問題が発生しませんでした。

$ python ecpcc2.py
4
{0: u'Name', 1: u'Day', 2: u'Magnitude', 3: u'NumOfDeaths', 4: u'DeadOrAlive'}
<type 'unicode'>
<type 'str'>
・ヨ東大震災Traceback (most recent call last):
  File "ecpcc2.py", line 35, in <module>
    print rs.Fields.Item(0).Value.encode('cp932')         #=> 関東大震災
IOError: [Errno 0] Error

2014-06-26

wxHaskell :: Notebook で tab を選択したときのイベントを取得する

| 11:03 |

f:id:sirocco:20140626110155j:image

radio box や list box 、choice は on selectによって選択したときのイベントを取得できますが、NotebookにはSelectingインスタンスがありません。

そこで on click イベントによりどこのタブがクリックされたか判定します。

  • notebookHitTest :: Notebook a -> Point -> Ptr CInt -> IO Int

 notebookHitTestの3番目の引数Haskellなのにポインタ渡しです。

そこで malloc でメモリを確保し、pokeで値を書き込み、そのアドレスを返す関数を作ります。

flag :: Ptr CInt
flag  =  unsafePerformIO flag' where
           flag' = do 
             work <- malloc::IO (Ptr CInt) 
             poke work (fromIntegral wxBK_HITTEST_ONPAGE)
             return work
  • GetSelectionは変化がひとつ遅れます。タブが変化したときはGetSelection変化せず、ひとつ前のSelectionを返します。
onMouse :: Notebook() -> Point -> IO ()
onMouse nb p = do
  propagateEvent
  i  <- notebookHitTest nb p flag
  n  <- notebookGetSelection nb
  logMessage ("Notebook index: " ++ show i ++ " GetSelection: " ++ show n)
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{--------------------------------------------------------------------------------
 Copyright (c) Daan Leijen 2003
 wxWindows License.

 Demonstrates: 
 - many different kind of controls
 - message logging.

$ ghc -Wall -package wx -o Controls.exe Controls.hs
--------------------------------------------------------------------------------}
module Main where

import Graphics.UI.WX
import Graphics.UI.WXCore 
import System.IO.Unsafe
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.Ptr
import Foreign.C.Types

main :: IO ()
main = start gui

gui :: IO ()
gui
  = do -- main gui elements: frame, panel, text control, and the notebook
       f       <- frame [text := "Controls"]
       p       <- panel    f []
       nb      <- notebook p []

       textlog <- textCtrl p [enabled := False, wrap := WrapNone] 

       -- use text control as logger
       textCtrlMakeLogActiveTarget textlog
       logMessage "logging enabled"              
       -- set f [on closing :~ \prev -> do logSetActiveTarget oldlog; logDelete log; prev]

       -- button page
       p1   <- panel  nb []

       ok   <- button p1 [text := "Ok", on command := logMessage "ok button pressed"]
       quit <- button p1 [text := "Quit", on command := close f]

       -- radio box page
       p2   <- panel  nb []
       let rlabels = ["first", "second", "third"]
       r1   <- radioBox p2 Vertical rlabels   [text := "radio box", on select ::= logSelect]
       r2   <- radioBox p2 Horizontal rlabels [tooltip := "radio group two", on select ::= logSelect]
       rb1  <- button   p2 [text := "disable", on command ::= onEnable r1]

       -- choice
       p3   <- panel nb []
       let clabels = ["mies","noot","aap"]
       c1   <- choice p3 [tooltip := "unsorted choices", on select ::= logSelect, sorted  := False, items := clabels]
       c2   <- choice p3 [tooltip := "sorted choices", on select ::= logSelect, sorted  := True, items := clabels] 
       cb1  <- button p3 [text := "disable", on command ::= onEnable c1]

       -- list box page
       p4   <- panel nb []
       sl1  <- singleListBox p4 
                  [items      := clabels
                  ,tooltip    := "unsorted single-selection listbox"
                  ,on select ::= logSelect]
       sl2  <- singleListBox p4 
                  [items      := clabels
                  ,tooltip    := "sorted listbox"
                  ,on select ::= logSelect, sorted     := True]
       sc1  <- checkBox p4 [text := "enable the listbox", checked := True, on command := set sl1 [enabled :~ not]]

       -- slider/gauge page
       p5   <- panel nb []
       s    <- hslider p5 True {- show labels -} 1 100 [selection := 50]
       g    <- hgauge  p5 100 [selection := 50]
       set s [on command := do{ i <- get s selection; set g [selection := i]} ]

       let tab1 = tab "buttons"   (container p1(margin 10 (floatCentre(row 5 [widget ok, widget quit]))))
           tab2 = tab "radio box" (container p2(margin 10 (column 5 [hstretch (widget rb1), row 0 [floatLeft (widget r1),floatRight(widget r2)]])))
           tab3 = tab "choice"    (container p3(margin 10 (column 5 [hstretch (widget cb1), row 0 [floatLeft (widget c1),floatRight(row 5 [label "sorted: ", widget c2])]])))
           tab4 = tab "listbox"   (container p4(margin 10 (column 5 [ hstretch (dynamic (widget sc1)), floatLeft (row 0 [widget sl1, widget sl2])])))
           tab5 = tab "slider"    (container p5(margin 10 (column 5 [hfill (widget s),hfill (widget g) ,glue ])))
           nbtab= tabs nb [tab1, tab2,tab3,tab4,tab5]

       -- ここでNotebookの選択イベントを設定
       set nb [on click := onMouse nb]
       -- specify layout
       set f [layout :=
              container p $
                column 0
                   [ nbtab, fill $ minsize (sz 100 200) $ widget textlog ]
             , clientSize := sz 800 300 ]
       return ()

  where
    -- logSelect :: (Selection w, Items w String) => w -> IO ()
    logSelect w
      = do i <- get w selection
           s <- get w (item i)
           logMessage ("selected index: " ++ show i ++ ": " ++ s)

    onEnable w b
      = do set w [enabled :~ not]
           enable <- get w enabled
           set b [text := (if enable then "disable" else "enable")]


flag :: Ptr CInt
flag  =  unsafePerformIO flag' where
           flag' = do 
             work <- malloc::IO (Ptr CInt) 
             poke work (fromIntegral wxBK_HITTEST_ONPAGE)
             return work

onMouse :: Notebook() -> Point -> IO ()
onMouse nb p = do
  propagateEvent
  i  <- notebookHitTest nb p flag
  n  <- notebookGetSelection nb
  putStrLn (show (i,n, i == n))

-- kindof :: Object a -> String -> IO ()
kindof obj className
  = do classInfo <- classInfoFindClass className
       if (objectIsNull classInfo)
        then logMessage ("kindof " ++ className ++ ": no such class")
        else if (objectIsNull obj)
              then logMessage ("kindof " ++ className ++ ": null object")
              else do haskind <- objectIsKindOf obj classInfo
                      logMessage ("kindof " ++ className ++ ": " ++ show haskind)
  • withを使えばunsafePerformIOも使わずにすむ。
import Foreign.Marshal.Utils

onMouse :: Notebook() -> Point -> IO ()
onMouse nb p = do
  propagateEvent
  i  <- with (fromIntegral wxBK_HITTEST_ONPAGE)  (\ptr -> notebookHitTest nb p ptr)
  n  <- notebookGetSelection nb
  logMessage ("Notebook index: " ++ show i ++ " GetSelection: " ++ show n)

2014-03-24

正常にパース出来た場合はJust、失敗した場合はNothingを返すmaybeRead

| 17:59 |

read関数文字列から指定された型のデータを生成します。

型が指定されない場合、read関数はどんな型に変換すれば良いか分からないので例外を発生します。

また、パースにエラーがある場合にも、例外を発生します。

> read "123"::Int
-- > 123
-- 型が指定されない場合
> read "3.14"

<interactive>:86:1:
    No instance for (Read a0) arising from a use of `read'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Read GHC.IO.Exception.ExitCode
        -- Defined in `GHC.IO.Exception'
      instance Read () -- Defined in `GHC.Read'
      instance (Read a, Read b) => Read (a, b) -- Defined in `GHC.Read'
      ...plus 44 others
    In the expression: read "3.14"
    In an equation for `it': it = read "3.14"
-- パースにエラーがある場合
> read "abc"::Int
*** Exception: Prelude.read: no parse
  • 例外を発生させるのではなく失敗を含むMaybe型を返して欲しい

例外を補足し、正常にパース出来た場合はJust、パースに失敗した場合はNothingを返すmaybeReadの例がStack Overflowにありました。

maybeRead :: Read a => String -> Maybe a
maybeRead s = case reads s of
    [(x, "")] -> Just x
    _         -> Nothing
> maybeRead "abc"::Maybe Int
-- > Nothing
> maybeRead "123"::Maybe Int
-- > Just 123

Data.Time Data.Time.Calendar>  maybeRead "2000-01-01"::Maybe Day
-- > Just 2000-01-01
Data.Time Data.Time.Calendar>  maybeRead "abc"::Maybe Day
-- > Nothing
  • reads 関数が重要な役目を持っているようです。

reads 関数を少しいじってみます。

>  reads "123" ::[(Int,String)]
-- > [(123,"")]
>  reads "123 456" ::[(Int,String)]
-- > [(123," 456")]
>  reads "123abc" ::[(Int,String)]
-- > [(123,"abc")]
>  reads "2014-03-24hello,world!" ::[(Day,String)]
-- > [(2014-03-24,"hello,world!")]
  • try により Either型を返す。
Prelude Control.Exception> try (print (read "123"::Int)) ::IO (Either SomeException ())
123
-- > Right ()

Prelude Control.Exception> try (print (read "qwe"::Int)) ::IO (Either SomeException ())
-- > Left Prelude.read: no parse

Prelude Control.Exception> try (evaluate (read "123"::Int)) ::IO (Either SomeException Int)
-- > Right 123
Prelude Control.Exception> try (evaluate (read "1q23"::Int)) ::IO (Either SomeException Int)
-- > Left Prelude.read: no parse
main = do
    result <- tryJust selectDivByZero (evaluate $ 5 `div` 0)
    case result of
        Left what -> putStrLn $ "Division by " ++ what
        Right val -> putStrLn $ "The answer was: " ++ show val
  where
    selectDivByZero :: ArithException -> Maybe String
    selectDivByZero DivideByZero = Just "zero"
    selectDivByZero _ = Nothing

2014-01-13

GHC の ScopedTypeVariables オプション

| 17:44 |

Rosetta Code にあるDetect division by zeroコンパイルしてみたのですが、GHC 7.6.3ではエラーになってしまいます。

出力されたエラーメッセージで検索すると arising from a use of `Control.Exception.catch’ がみつかりました。

{-# LANGUAGE ScopedTypeVariables #-}

を先頭に書くかGHCi で

> :set -XScopedTypeVariables

を指定する必要があります。

(e :: C.SomeException)を指定しないとエラーになりました。

{-# LANGUAGE ScopedTypeVariables #-}
import qualified Control.Exception as C

check x y = C.catch (x `div` y `seq` return False) (\(e :: C.SomeException) -> return True)

Main> check 1 3 -- > False
Main> check 1 0 -- > True