PyGTKã§ããªã¼ãã¥ã¼ã«ãªã¹ãã®ãã¼ã¿(ListStore)ã表示(é ç®ãGUIä¸ã§è¿½å /åé¤ããã¼ã¿ã®ä¸¦ã¹æ¿ããå ¥ãæ¿ããªã©)
PyGTKã«ãããããªã¼ãã¥ã¼ã«é¢ãã¦ããã¾ã§ã«å¹¾ã¤ãã®ä¾ã¨ã¡ã¢ãæ¸ãã¦ãããããã¼ã¿ã®è¿½å ã«é¢ãã¦ã¯ãããããç¨æãã¦ããããã®ãæµãè¾¼ãã§ããã ãã§ãåé¤ãã§ããªãã£ããããã§ä»åã¯é
ç®ãGUIä¸ã§è¿½å /åé¤ã§ããããã«ããã
ã¾ããåæã«
- é ç®ã®é¸æã«ã¤ãã¦è¤æ°ã®é¸æãå¯è½ã«
- ã³ã©ã ãå·¦å³ãã©ãã°ããªã¹ãé ç®(ãã¼ã¿)ãä¸ä¸ãã©ãã°ã§ç§»åå¯è½
ã¨ããä¿®æ£ãããã
ã¡ã¢
- ããªã¼ãã¥ã¼é ç®ã®è¤æ°é¸æãå¯è½ã«ããã«ã¯gtk.TreeViewオブジェクトã®get_selection()ã§å¾ãããgtk.TreeSelectionオブジェクトã®ã¡ã³ãé¢æ°set_mode()ã§gtk.SELECTION_MULTIPLEãæå®ãã
- ã³ã©ã ã«ã¤ãã¦å¤ã«ãã並ã¹æ¿ããå¯è½ã«ããã«ã¯gtk.TreeViewColumnオブジェクトã®ã¡ã³ãé¢æ°set_sort_column_id()ã§ã³ã©ã ã®çªå·ãæå®
- ã³ã©ã ã®å·¦å³ãã©ãã°ã«ããå ¥ãæ¿ããå¯è½ã«ããã«ã¯åãªãã¸ã§ã¯ãã®set_reorderable()ã§Trueãæå®
- ããªã¼ãã¥ã¼é ç®ãä¸ä¸ãã©ãã°ã§ç§»åå¯è½ã«ããã«ã¯gtk.TreeViewオブジェクトã®ã¡ã³ãé¢æ°set_reorderable()ã«Trueãæå®
- ãã¼ã¿ã®è¿½å ã«ã¤ãã¦ã¯ãGUIé¨åããå¤ã®åå¾ãè¡ãgtk.ListStoreオブジェクトã®append()ã§è¿½å ãã¨ããæµãã¨ãªããå¤ã®åå¾ã«ä½¿ç¨ããã¡ã³ãé¢æ°ã¯ãªãã¸ã§ã¯ã(é¨å)ãã¨ã«ç°ãªã
- æ§å¥ã®ã¢ã¤ã³ã³ã«ã¤ãã¦ã¯ã³ã³ãããã¯ã¹ã®å¤ãå¤å¥å¾ããã«åã£ãç»åãã¼ã¿(gtk.gdk.Pixbufオブジェクト)ã渡ãããã«ãã
- ãã¼ã¿ã®ä¸é¨åé¤ã«ã¤ãã¦ã¯gtk.ListStoreオブジェクトã®ã¡ã³ãé¢æ°remove()ã«ããããgtk.TreeSelectionオブジェクトã®get_selected()(åç¬é¸æã¢ã¼ãæ)ãget_selected_rows()(è¤æ°é¸æã¢ã¼ãæ)ããå¾ãããgtk.TreeIterオブジェクトãç¨ãã¦é ç®ãæå®ãã
- ListStore/TreeStoreå ã®ãã¼ã¿ã®ä¸æ¬åé¤ã¯ããããã®ã¡ã³ãé¢æ°clear()ã§è¡ã
- get_selected_rows()ã使ç¨ãã¦è¤æ°ã®gtk.TreeIterオブジェクトãå¾ãã«ã¯ãiters = [model.get_iter(path) for path in selected]ãã®ãããªæ¸ãæ¹ã便å©(ãã¨ã¯foræã§åãªãã¸ã§ã¯ãã«ã¤ãã¦å¦çããã°OK)
ã³ã¼ãä¾
ãPyGTKでツリービューにリストのデータ(ListStore)を表示(データを変更可能にする・コード例)ãã®sexmark.pyãå¥éå¿
è¦ã
ä¾ã«ãã£ã¦ããã®ä¸ã§ä½¿ç¨ããååã¯æ¶ç©ºã®ãã®ã§ãããå®å¨ã®å人åãå£ä½åãªã©ã¨ä¸è´ãããã®ããã£ãã¨ãã¦ãé¢ä¿ã¯ãªãã
#! /usr/bin/python # -*- encoding: utf-8 -*- import sys try: import pygtk pygtk.require('2.0') except: pass try: import gtk except: print >> sys.stderr, 'Error: PyGTK is not installed' sys.exit(1) try: import sexmark except: print >> sys.stderr, 'Error: sexmark.py required' sys.exit(1) class TreeViewWithColumn(gtk.TreeView): """ ã³ã©ã ãå«ãã ããªã¼ãã¥ã¼ """ ( COLUMN_NUM, COLUMN_SEX, COLUMN_FAMILY, COLUMN_GIVEN, ) = range(4) def __init__(self, *args, **kwargs): gtk.TreeView.__init__(self, *args, **kwargs) self.renderer_num = gtk.CellRendererText() self.renderer_num.connect('edited', self.on_text_edited, self.COLUMN_NUM) # ã³ã©ã çªå·ãã¦ã¼ã¶ãã¼ã¿ã¨ãã¦è¿½å ã§æ¸¡ãã¦ãã self.renderer_num.set_property('editable', True) self.renderer_family = gtk.CellRendererText() self.renderer_family.connect('edited', self.on_text_edited, self.COLUMN_FAMILY) self.renderer_family.set_property('editable', True) self.renderer_given = gtk.CellRendererText() self.renderer_given.connect('edited', self.on_text_edited, self.COLUMN_GIVEN) self.renderer_given.set_property('editable', True) # ã³ã©ã ã®è¨å® self.col_num = gtk.TreeViewColumn('No.', self.renderer_num, text=self.COLUMN_NUM) self.col_num.set_sort_column_id(self.COLUMN_NUM) # 並ã¹æ¿ã self.col_num.set_reorderable(True) # å·¦å³ã®ãã©ãã°ã§ã³ã©ã å ¥ãæ¿ã self.col_sex = gtk.TreeViewColumn('Sex', gtk.CellRendererPixbuf(), pixbuf=self.COLUMN_SEX) self.col_sex.set_reorderable(True) self.col_family = gtk.TreeViewColumn('Family name', self.renderer_family, text=self.COLUMN_FAMILY) self.col_family.set_sort_column_id(self.COLUMN_FAMILY) self.col_family.set_reorderable(True) self.col_given = gtk.TreeViewColumn('Given name', self.renderer_given, text=self.COLUMN_GIVEN) self.col_given.set_sort_column_id(self.COLUMN_GIVEN) self.col_given.set_reorderable(True) # ã³ã©ã ã追å self.append_column(self.col_num) self.append_column(self.col_sex) self.append_column(self.col_family) self.append_column(self.col_given) # è¤æ°è¡é¸æãå¯è½ã«ãã self.get_selection().set_mode(gtk.SELECTION_MULTIPLE) # ã³ã³ããã¹ãã¡ãã¥ã¼ self.item_changesex = gtk.MenuItem('_Change Sex') self.menu_popup = gtk.Menu() self.menu_popup.add(self.item_changesex) self.menu_popup.show_all() self.item_changesex.connect('activate', self.on_changesex_activated) self.connect('button_press_event', self.on_button_press_event) def on_text_edited(self, widget, path, new_text, col): """ ããã¹ãç¨ã»ã«ãç·¨éãããã¨ãã®å¦ç col(ã¦ã¼ã¶ãã¼ã¿)ã¯ã³ã©ã çªå· """ # get_model()ã§ããªã¼ãã¥ã¼ã«é¢é£ä»ãããããã¼ã¿ãåãåºã㦠# å¼æ°ã®æ å ±ã¨ãããã¦ãã¼ã¿ã®å¤ãå¤æ´ãã model = self.get_model() if col == self.COLUMN_NUM: try: model.set_value(model.get_iter(path), col, int(new_text)) except ValueError: # æ´æ°ä»¥å¤ãæå®ããã pass else: model.set_value(model.get_iter(path), col, new_text) def on_button_press_event(self, widget, event): """ ããªã¼ãã¥ã¼ä¸ã§ãã¦ã¹ãã¿ã³ãæ¼ãããã¨ãã®å¦ç """ if event.button == 3: # ãã¼ã¿ããªãé¨åã§ã³ã³ããã¹ãã¡ãã¥ã¼ãéããªãããã«ãã # (æ¬ã¹ã¯ãªããã®å ´åããã¼ã¿ã®é·ããæ°äººåã«ããªãã¨å¹æã¯ç¢ºèªã§ããªã) # get_path_at_pos()ã¯TreeViewå ã®åº§æ¨ããé ç®ã®ãã¹ãåå¾ path_at_pos = self.get_path_at_pos(int(event.x), int(event.y)) # ã¯ãªãã¯ããå ´æã«é ç®ãããã®ã確èªã§ããå ´åã®ã¿ãããã¢ãããã if path_at_pos: # Noneã®å ´åããã self.menu_popup.popup(None, None, None, event.button, event.time) def on_changesex_activated(self, widget): """ ããªã¼ãã¥ã¼ä¸ã®ã³ã³ããã¹ãã¡ãã¥ã¼é ç®ãé¸æããã¨ãã®å¦ç æ§å¥ã®ã¢ã¤ã³ã³ãå¤æ´ """ # ç¾å¨é¸æããã¦ããé ç®ãåãåºã # get_selected()ã¯è¤æ°é¸æå¯ã¢ã¼ãã§ã¯ä½¿ç¨ã§ããªã # get_selected_rows()ãç¨ããå¦çã®ä»æ¹ã«ã¤ãã¦ã¯ # PyGTK FAQã®ãHow do I delete multiple selections?ããåç § (model, selected) = self.get_selection().get_selected_rows() iters = [model.get_iter(path) for path in selected] for iter in iters: # ç¾å¨å¤ãmaleã§ããã°femaleã«ãfemaleãªãmaleã«å¤æ´ if model.get_value(iter, self.COLUMN_SEX) == SexIcon.male: model.set_value(iter, self.COLUMN_SEX, SexIcon.female) else: model.set_value(iter, self.COLUMN_SEX, SexIcon.male) class SexIcon: """ æ§å¥ã®ã¢ã¤ã³ã³ãã¼ã¿ã®Pixbufãä¿æ åãã¼ã¿ã¯ã[æ¬ã¯ã©ã¹å].[ã¡ã³ãå¤æ°]ãã§åãåºã """ male = gtk.gdk.pixbuf_new_from_xpm_data(sexmark.male_icon_xpm) female = gtk.gdk.pixbuf_new_from_xpm_data(sexmark.female_icon_xpm) class MainWindow(gtk.Window): """ ã¡ã¤ã³ã¦ã£ã³ã㦠""" # ç´æ¥ã¦ã£ã³ãã¦ã¨ã¯é¢ä¿ãªããããã¼ã¿ã¯ä¾¿å®ä¸ããã«ç¨æãã¦ãããã¨ã«ãã data = \ [ (1, SexIcon.male, 'Tanaka', 'Ichiro'), (2, SexIcon.female, 'Yamana', 'Hanako'), (3, SexIcon.male, 'Urashima', 'Saburo'), (4, SexIcon.male, 'Kurusu', 'Santa'), (5, SexIcon.male, 'Handa', 'Fuuta'), (6, SexIcon.female, 'Umeno', 'Tsubomi'), (7, SexIcon.male, 'Yoshi', 'Yaruzo'), (8, SexIcon.female, 'Kawai', 'Nuko'), (9, SexIcon.male, 'Hoshi', 'Kintaro'), (10, SexIcon.female, 'Shirayuki', 'Himeko'), (11, SexIcon.female, 'Ashigaka', 'Yui'), (12, SexIcon.female, 'Ageyanagi', 'Masako'), (13, SexIcon.male, 'Torino', 'Kenta'), (14, SexIcon.male, 'Kubota', 'Mochio'), (15, SexIcon.female, 'Kuroi', 'Sora'), (16, SexIcon.male, 'Hirai', 'Shin'), (17, SexIcon.female, 'Akai', 'Midori'), (18, SexIcon.female, 'Nakano', 'Anko'), (19, SexIcon.male, 'Imai', 'Takeo'), (20, SexIcon.male, 'Kouno', 'Torio'), (21, SexIcon.male, 'Yoshino', 'Yasu'), (22, SexIcon.male, 'Komatsu', 'Taro'), (23, SexIcon.male, 'Kondo', 'Musashi'), (24, SexIcon.male, 'Ono', 'Ken'), (25, SexIcon.male, 'Mochida', 'Usuichi'), (26, SexIcon.female, 'Mochida', 'Kineko'), (27, SexIcon.female, 'Honma', 'Kayo'), (28, SexIcon.male, 'Matsuno', 'Sarunosuke'), (29, SexIcon.female, 'Nishi', 'Minami'), (30, SexIcon.female, 'Usui', 'Hikaru'), (31, SexIcon.male, 'Sato', 'Toshio'), (32, SexIcon.male, 'Doi', 'Tsubasa'), (33, SexIcon.female, 'Ishimaru', 'Denko'), (34, SexIcon.female, 'Usami', 'Mimi'), (35, SexIcon.male, 'Hattori', 'Shinobu'), (36, SexIcon.female, 'Kago', 'Yuri'), (37, SexIcon.male, 'Takeda', 'Ingen'), (38, SexIcon.male, 'Kai', 'Dankichi'), (39, SexIcon.male, 'Okusa', 'Ben'), (40, SexIcon.male, 'Hara', 'Tatsuo'), (41, SexIcon.female, 'Mizuno', 'Shizuku'), (42, SexIcon.female, 'Baba', 'Nana'), ] def __init__(self, *args, **kwargs): gtk.Window.__init__(self, *args, **kwargs) # ã·ã§ã¼ãã«ãããã¼(ã¢ã¯ã»ã©ã¬ã¼ã¿) self.accelgroup = gtk.AccelGroup() self.add_accel_group(self.accelgroup) # ã¡ãã¥ã¼é ç® self.item_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.accelgroup) self.menu_file = gtk.Menu() self.menu_file.add(self.item_quit) self.item_file = gtk.MenuItem('_File') self.item_file.set_submenu(self.menu_file) self.menubar = gtk.MenuBar() self.menubar.append(self.item_file) # ãã¼ã¿è¿½å ç¨ãã©ã¼ã self.label_num = gtk.Label('No.:') self.label_sex = gtk.Label('Sex:') self.label_familyname = gtk.Label('Family name:') self.label_givenname = gtk.Label('Given name:') self.spinbtn_num = gtk.SpinButton(gtk.Adjustment(1, 1, 999, 1, 0, 0)) self.combo_sex = gtk.combo_box_new_text() self.combo_sex.append_text('Male') self.combo_sex.append_text('Female') self.combo_sex.set_active(0) # 0çª(male)ãæ¢å®ã®é ç®ã«ãã self.entry_familyname = gtk.Entry() self.entry_givenname = gtk.Entry() self.button_add = gtk.Button(stock=gtk.STOCK_ADD) self.button_delete = gtk.Button(stock=gtk.STOCK_DELETE) self.button_clear = gtk.Button(stock=gtk.STOCK_CLEAR) # ããªã¼ãã¥ã¼ self.treeview = TreeViewWithColumn(model=gtk.ListStore(int, gtk.gdk.Pixbuf, str, str)) self.treeview.set_rules_hint(True) self.treeview.set_reorderable(True) # ä¸ä¸ãã©ãã°ã§ç§»åã§ããããã«ãã # ããªã¼ãã¥ã¼åãã¹ã¯ãã¼ã«ã¦ã£ã³ã㦠self.sw = gtk.ScrolledWindow() self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(self.treeview) # ã¬ã¤ã¢ã¦ãç¨ã³ã³ãã self.hbox_num = gtk.HBox() self.hbox_num.pack_start(self.label_num, expand=False, fill=False) self.hbox_num.pack_end(self.spinbtn_num, expand=False, fill=False) self.hbox_sex = gtk.HBox() self.hbox_sex.pack_start(self.label_sex, expand=False, fill=False) self.hbox_sex.pack_end(self.combo_sex, expand=False, fill=False) self.hbox_familyname = gtk.HBox() self.hbox_familyname.pack_start(self.label_familyname, expand=False, fill=False) self.hbox_familyname.pack_end(self.entry_familyname, expand=False, fill=False) self.hbox_givenname = gtk.HBox() self.hbox_givenname.pack_start(self.label_givenname, expand=False, fill=False) self.hbox_givenname.pack_end(self.entry_givenname, expand=False, fill=False) self.vbox_input = gtk.VBox() # å ¥åãã©ã¼ã ã®åæ°´å¹³ããã¯ã¹ã縦ã«ä¸¦ã¹ã self.vbox_input.pack_start(self.hbox_num, expand=False, fill=False) self.vbox_input.pack_start(self.hbox_sex, expand=False, fill=False) self.vbox_input.pack_start(self.hbox_familyname, expand=False, fill=False) self.vbox_input.pack_start(self.hbox_givenname, expand=False, fill=False) self.vbox_buttons = gtk.VBox() # ãã¿ã³ã縦ã«ä¸¦ã¹ã self.vbox_buttons.pack_start(self.button_add) self.vbox_buttons.pack_start(self.button_delete) self.vbox_buttons.pack_start(self.button_clear) self.hbox = gtk.HBox() # 2ã¤ã®å¤§ããªæ¨ªæ¹åã®ã¾ã¨ã¾ã self.hbox.pack_start(self.vbox_input) self.hbox.pack_start(self.vbox_buttons) self.vbox = gtk.VBox() # ã¦ã£ã³ãã¦å ¨ä½ã縦ã«åå²ãããã® self.vbox.pack_start(self.menubar, expand=False, fill=False) self.vbox.pack_start(self.hbox, expand=False, fill=False) self.vbox.pack_start(self.sw) # ã·ã°ãã« self.connect('delete_event', gtk.main_quit) self.item_quit.connect('activate', gtk.main_quit) self.button_add.connect('clicked', self.on_add_clicked) self.button_delete.connect('clicked', self.on_delete_clicked) self.button_clear.connect('clicked', self.on_clear_clicked) # ãã¼ã¿è¿½å for rec in self.data: self.treeview.get_model().append(rec) # ã¦ã£ã³ã㦠self.add(self.vbox) self.set_size_request(350, 300) def on_add_clicked(self, widget): """ ã¢ãã«ã«ãã¼ã¿ã追å """ num = int(self.spinbtn_num.get_value()) familyname = self.entry_familyname.get_text() givenname = self.entry_givenname.get_text() # 空ã®é ç®ãããã¨è¿½å ããªããã¨ã«ãã if num == '' or familyname == '' or givenname == '': return # ããã¹ãå ¥åæ¬ã空ã«ãã self.entry_familyname.set_text('') self.entry_givenname.set_text('') # æ§å¥ã¯é¨åãè¿ãçªå·ã«ãã£ã¦ãã¼ã¿ãä½æãã if self.combo_sex.get_active() == 0: sex = SexIcon.male else: sex = SexIcon.female # ã¿ãã«ã渡ãã¦ãã¼ã¿è¿½å self.treeview.get_model().append((num, sex, familyname, givenname)) def on_delete_clicked(self, widget): """ é¸æãããè¤æ°ã®é ç®ãã¢ãã«ããåé¤ """ (model, selected) = self.treeview.get_selection().get_selected_rows() iters = [model.get_iter(path) for path in selected] for iter in iters: model.remove(iter) def on_clear_clicked(self, widget): """ ã¢ãã«ã®ãã¼ã¿ãå ¨ã¦æ¶ã """ self.treeview.get_model().clear() class PyGTKTreeViewListStoreTest3: """ ãªã¹ããç¨ããããªã¼ãã¥ã¼ã®ãã¹ã3 """ def main(self): """ ã¢ããªã±ã¼ã·ã§ã³ã®ã¡ã¤ã³å¦ç """ win = MainWindow() win.show_all() gtk.main() if __name__ == '__main__': app = PyGTKTreeViewListStoreTest3() app.main()
追å ãããã¼ã¿ãå
¥å
ãã¼ã¿è¿½å å¾
ã³ã©ã ã®ãã©ãã°ã«ãã移å(é çªå
¥ãæ¿ã)
é
ç®ã®ãã©ãã°ã«ãã移å
é¢é£è¨äº:
- PyGTKでツリービューにリストのデータ(ListStore)を表示(概要とメモ)
- PyGTKでツリービューにリストのデータ(ListStore)を表示(簡単な例)
- PyGTKでツリービューにリストのデータ(ListStore)を表示(データを変更可能にする・メモ)
- PyGTKでツリービューにリストのデータ(ListStore)を表示(データを変更可能にする・コード例)
- PyGTKでツリービューに階層を持ったデータ(TreeStore)を表示
- PyGTKでツリービューにリストのデータ(ListStore)を表示(モデルの内容を取り出す)
- PyGTKでツリービューにリストのデータ(ListStore)を表示(ボタンからデータの順番を入れ替える・コード例)
åèURL: