XRCedでカスタムウィジェット

Gtkでやったときの経験上、wx.TreeCtrlは派生クラスを作った方がいいでしょう。

import wx

class AoisoWxTreeCtrl(wx.TreeCtrl):

    def __init__(self, parent):
        wx.TreeCtrl.__init__(self, parent)
        return

XRCed上では?マークのカスタムウィジェット(wx用語ではUnknown Widget)を配置しておきます。IDは"ID_TREE_CTRL"にしておきます。

self.treeCtrl = AoisoWxTreeCtrl(self)
AttachUnknownControl("ID_TREE_CTRL", self.treeCtrl, self)

でいけるかと思ったんですが甘かった。TreeCtrlの親はPanelなのでselfでなくPanelを指定する。まずこのPanelにもIDをつける。"ID_TREE_PANEL"。

#NG
panel = app.res.LoadPanel(self, "ID_TREE_PANEL")
self.treeCtrl = AoisoWxTreeCtrl(panel)
app.res.AttachUnknownControl("ID_TREE_CTRL", self.treeCtrl, self)

これでもダメ。どうやらpanel==Noneになってる。もしかしてLoadPanelの引数にもその直接の親を指定するの?? だとするとそうとう面倒くさい。そんなバカな・・・ね。

LoadPanelじゃなくてこういうのもやってみた。

id = app.res.GetXRCID("ID_TREE_PANEL")
panel = wxPyTypeCast( self.FindWindowById(id) , "wxPanel")

同じくpanel==None。ふと思い立ってXRCedからPythonコードをジェネレートしてみると

self.ID_TREE_PANEL = xrc.XRCCTRL(self, "ID_TREE_PANEL")

こ、これだけ? でも同じくいかない。

ところが、このジェネレートされたソースをみてふと思った。・・・あれ? さっきMainFrameのID変えたのがxrcファイルに反映されてない?? 結局IDミスという非常に凡ミスでした。まとめると以下でOK。

#OK
panel = xrc.XRCCTRL(self, "ID_TREE_PANEL")
self.treeCtrl = AoisoWxTreeCtrl(panel)
app.res.AttachUnknownControl("ID_TREE_CTRL", self.treeCtrl, panel)

以下でもOK。(wxPyTypeCastはやらなくてもOK)

#OK
id = app.res.GetXRCID("ID_TREE_PANEL")
panel = wxPyTypeCast( self.FindWindowById(id) , "wxPanel")
self.treeCtrl = AoisoWxTreeCtrl(panel)
app.res.AttachUnknownControl("ID_TREE_CTRL", self.treeCtrl, panel)

ちなみにLoadPanel案はセグメンテーション違反になる。

#NG
panel = app.res.LoadPanel(self, "ID_TREE_PANEL")
self.treeCtrl = AoisoWxTreeCtrl(panel)
app.res.AttachUnknownControl("ID_TREE_CTRL", self.treeCtrl, panel)

とういうわけでした。ちゃんちゃん。