さーて、今日も Python だ。
ところで先月のウチへの検索ワードを晒す。
Python や PyGtk 関係はいずこ、、、、、orz
SEO もクソもあったもんじゃねぇ、でも続ける。
つーことで gEdit も内部で使っている GtkUIManager とやらを使ってみたい。
内部ではどう使われているかなんか知らないよ、当然実装方法なんか解らない。
日本語で PyGtk を探しても見つかるはずがないので最初から米国の google で検索!
私自身がこうだもの、そりゃ SEO にならない、、、、orz
公式のの「16.7. The UIManager」が普通に一番解りやすい。
つまり gtk.UIManager のインスタンスに読み込ませるとオブジェクトが作られる。
ソレを get_widget メソッドで取り出してパッキングする。
という流れでいいみたい。
ついでに GtkActionGroup の使い方も解りやすく書いてくれている。
XML で action 属性を同じ str にしたものは同じ動作をするわけだ。
そういえば Delphi にも TActionList なんてのがあった。
というか Palepoli v2 で使っていた、便利なんだよね。
メニューと右クリックメニューとボタンの動作指定やハンドラが共用できて。
倍率指定のラジオボタンをメインメニューと右クリックメニューで同じにする必要がある。
ハンドラは同じ名前を指定すればいいだけだがラジオの位置は別々に変更を迫られる。
だけどこれを使えば解決だ、位置も XML で指定できるから同じにする必要はない。
早速書いてみようと思ったけどココ何か説明がたりない。
add_radio_actions には GtkRadioActionEntry を入れなきゃいけないんだが。
詳しくは Devhelp を見てね、つーことで昨日のコードに書きたし。
#!/usr/bin/env python #-*- coding:utf-8 -*- ui_str = """<ui> <menubar name="MenuBar"> <menu action="File"> <menuitem action="quit"/> </menu> <menu action="View"> <menuitem action="x00"/> <menuitem action="x10"/> <menuitem action="x20"/> <menuitem action="x30"/> <menuitem action="x05"/> <menuitem action="x15"/> <menuitem action="x25"/> <menuitem action="xs1"/> <menuitem action="xs2"/> <menuitem action="xs3"/> </menu> </menubar> <popup> <menuitem action="x00"/> <menuitem action="x10"/> <menuitem action="x20"/> <menuitem action="x30"/> <menuitem action="x05"/> <menuitem action="x15"/> <menuitem action="x25"/> <menuitem action="xs1"/> <menuitem action="xs2"/> <menuitem action="xs3"/> <separator/> <menuitem action="quit"/> </popup> </ui>""" import gtk import common class TestWindow(gtk.Window): def __init__(self): # 継承のお約束 gtk.Window.__init__(self) # # メニューを作る # # まず GtkUIManager 作成 uimanager = gtk.UIManager() # GtkAccelGroup を得る accelgroup = uimanager.get_accel_group() self.add_accel_group(accelgroup) # GtkActionGroup 作成 actiongroup = gtk.ActionGroup("sasakimamenu") # GtkActionEntry を作成して突っ込む # name, stock_id, label, accelerator, tooltip, callback actions0 = [("quit", gtk.STOCK_QUIT, "終了(_Q)", "<Control>Q", "さいなら", self.on_quit), ("File", None, "ファイル(_F)"), ("View", None, "表示(_V)")] #("Popup", None, "")] actiongroup.add_actions(actions0) # GtkRadioActionEntry の List を作成 # name, stock_id, label, accelerator, tooltip, value actions1 = [("x00", None, "ウインドサイズ", "0", "ウインドサイズ", 0), ("x10", None, "x1.0", "1", "x1.0", 1), ("x20", None, "x2.0", "2", "x2.0", 2), ("x30", None, "x3.0", "3", "x3.0", 3), ("x05", None, "x0.5", "4", "x0.5", 4), ("x15", None, "x1.5", "5", "x1.5", 5), ("x25", None, "x2.5", "6", "x2.5", 6), ("xs1", None, "set1", "7", "set1", 7), ("xs2", None, "set2", "8", "set1", 8), ("xs3", None, "set3", "9", "set1", 9) ] # GtkRadioAction を突っ込む # entries, value=0, on_change=None, user_data=None actiongroup.add_radio_actions(actions1, 0, self.on_size_change) # uimanager.insert_action_group(actiongroup, 0) uimanager.add_ui_from_string(ui_str) # Popup Menu を得る self.popup_menu = uimanager.get_widget('/popup') # セレクタの List を作っておく self.size_str = ["win","x1.0","x2.0","x3.0","x0.5","x1.5","x2.5","set1","set2","set3"] # おしまい # # ステータスバーを作る self.sb = common.CStatusBar(2, self) self.sb.label[0].set_text("こんどは") self.sb.label[1].set_text("menu を作ったよ") vb = gtk.VBox() # 最初にメニューを突っ込もうね menubar = uimanager.get_widget("/MenuBar") vb.pack_start(menubar, False) da = gtk.DrawingArea() vb.pack_start(da) vb.pack_start(self.sb, False, False, 0) self.add(vb) self.connect("delete-event", self.on_quit) # GDK イベントの有効化を行っておく da.set_events(gtk.gdk.BUTTON_PRESS_MASK) da.connect("button_press_event", self.on_button_down) self.resize(320, 240) self.show_all() def on_size_change(self, action, current): # ステータスバーにサイズの表示 self.sb.label[1].set_text(self.size_str[action.get_current_value()]) def on_quit(self, widget, event=None): # bye gtk.main_quit() return True def on_button_down(self, widget, event): # 右クリで PopupMenu if event.button == 3: self.popup_menu.popup(None, None, None, event.button, event.time) if __name__ == "__main__": w = TestWindow() gtk.main()
おぉメインメニューも右クリも完全に同じ動作だ、コイツは楽ちん。
実は右クリックメニューをどうするかで悩んでいたけどコレで決まりだ。
ちなみに Y901 はメインと右クリックで同じメニューを出していたので必要無かった。
とりあえず Ubuntu 9.04 ならこのコードで動く。
以前のバージョンは…確認用にそろそろ旧バージョンを VirtualBox に入れなきゃ。