【wxPython】メニューバーを付ける
追記: 2014/11/20 21:41
調べてみたら、もっとたくさん ID 用意されてた。
SpecialIDs - wxPyWiki
あと、新たに ID を追加する場合は wx.NewId
で生成する方が良いようだ。
メニューを追加する際は ID が必要だが、一部は事前に用意されている。
- wx.ID_UNDO
- wx.ID_REDO
- wx.ID_CUT
- wx.ID_COPY
- wx.ID_PASTE
新たに ID を用意するなら、別にこれらの ID を必ず使う必要はない。
メニューの UI の更新に関しては、wx.EVT_UPDATE_UI イベントを使うと良い。
# -*- coding: utf-8 -*- import wxversion wxversion.select("3.0") import wx import wx.html2 import wx.stc as stc import markdown #============================================================================== # 定数群 #------------------------------------------------------------------------------ MENU_FILE_CLOSE = 1 #============================================================================== # 関数群 #------------------------------------------------------------------------------ def update(): timer.Start(milliseconds=100, oneShot=True) def update_preview(): # 変数 html が空文字だと SetPage で反映されないので、html 要素など加えておく html = """\ <!DOCTYPE html> <html lang="ja"> <head><meta charset="utf-8"></head> <body>%s</body> </html> """ % convert_str_to_html(text.GetValue()) browser.SetPage(html, "") def convert_str_to_html(str): codehilite = "codehilite(force_linenos=True, guess_lang=False, css_class=syntax)" return markdown.markdown(str, ["extra", codehilite]) def exit_app(): dialog = wx.MessageDialog(frame, u"ウィンドウを閉じますか?", u"確認", wx.OK|wx.CANCEL|wx.ICON_QUESTION) result = dialog.ShowModal() if result == wx.ID_OK: frame.Destroy() # イベントハンドラ #------------------------------------------------------------------------------ def close_handler(event): exit_app() def char_handler(event): update() event.Skip() def timer_handler(event): update_preview() event.Skip() def update_ui_handler(event): menu_edit.Enable(id=wx.ID_UNDO, enable=text.CanUndo()) menu_edit.Enable(id=wx.ID_REDO, enable=text.CanRedo()) menu_edit.Enable(id=wx.ID_CUT, enable=text.CanCut()) menu_edit.Enable(id=wx.ID_COPY, enable=text.CanCopy()) menu_edit.Enable(id=wx.ID_PASTE, enable=text.CanPaste()) def menu_handler(event): id = event.GetId() if id == MENU_FILE_CLOSE: exit_app() return elif id == wx.ID_UNDO: text.Undo() elif id == wx.ID_REDO: text.Redo() elif id == wx.ID_CUT: text.Cut() elif id == wx.ID_COPY: text.Copy() elif id == wx.ID_PASTE: text.Paste() update() #============================================================================== # 処理 #------------------------------------------------------------------------------ if __name__ == "__main__": app = wx.App() # 多重起動チェック instance_name = u"%s-%s" % (app.GetAppName(), wx.GetUserId()) instance = wx.SingleInstanceChecker(instance_name) if instance.IsAnotherRunning(): exit() frame = wx.Frame(None, wx.ID_ANY, "Markdown test", size=(800, 600)) menu_bar = wx.MenuBar() menu_file = wx.Menu() menu_file.Append(MENU_FILE_CLOSE, u"閉じる\tCtrl+Q") menu_bar.Append(menu_file, u"ファイル") menu_edit = wx.Menu() menu_edit.Append(wx.ID_UNDO, u"取り消し\tCtrl+Z") menu_edit.Append(wx.ID_REDO, u"やり直し\tCtrl+Shift+Z") menu_edit.AppendSeparator() menu_edit.Append(wx.ID_CUT, u"カット\tCtrl+X") menu_edit.Append(wx.ID_COPY, u"コピー\tCtrl+C") menu_edit.Append(wx.ID_PASTE, u"ペースト\tCtrl+V") menu_bar.Append(menu_edit, u"編集") frame.Bind(wx.EVT_MENU, menu_handler) frame.SetMenuBar(menu_bar) sw = wx.SplitterWindow(frame, -1, style=wx.SP_LIVE_UPDATE) pane1 = wx.Panel(sw, -1) text = stc.StyledTextCtrl(pane1, wx.ID_ANY) text.SetMarginType(1, stc.STC_MARGIN_NUMBER) text.SetMarginWidth(1, 30) text.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "fore:#999999") text.SetLexer(stc.STC_LEX_MARKDOWN) text.Bind(wx.EVT_CHAR, char_handler) pane1_sizer = wx.BoxSizer() pane1_sizer.Add(text, 1, wx.EXPAND, 10) pane1.SetSizer(pane1_sizer) pane2 = wx.Panel(sw, -1) browser = wx.html2.WebView.New(pane2) pane2_sizer = wx.BoxSizer() pane2_sizer.Add(browser, 1, wx.EXPAND, 10) pane2.SetSizer(pane2_sizer) sw.SetSashGravity(0.5) sw.SplitVertically(pane1, pane2) timer = wx.Timer(frame) frame.Bind(wx.EVT_TIMER, timer_handler, timer) frame.Bind(wx.EVT_UPDATE_UI, update_ui_handler) frame.Bind(wx.EVT_CLOSE, close_handler) frame.Show() app.MainLoop()