HOME | 5. 関数のクラスを使ってクールなコードを書こう | Python | 7. Widget てんこ盛り画像 Viewer | download | 書き込む |
花の画像は素材屋ひなとん からいただきました。
まず、Tk.Listbox について説明してからプログラムを作っていきたいと思います。
図2
Tk.Listbox(master, **option)option は次の通りです。
属性 | 説明 |
---|---|
bg or background | 背景色 |
bd or borderwidth | 縁の幅 |
cursor | カーソルの形 |
font | フォント |
fg or foreground | 文字色 |
height | 表示する行数。pixel ではない。 |
highlightbackground | focus があるときの背景色 |
highlightcolor | focus があるときの文字色 |
highlightthickness | focus lighlight の厚さ |
relief | 縁の形 |
selectbackground | 選択されたときの背景色 |
selectborderwidth | 選択されたときの縁幅 |
selectforeground | 選択されたときの文字色 |
selectmode | 選択のモード。
|
takefocus | Tab キーによる widget の移動の対象にするかどうか。1: する。0: しない。 |
width | 1行の文字数。pixel 数ではない。デフォルトは 20 文字。 |
xscrollcommand | 横スクロークするときのコマンド。 |
yscrollcommand | 縦スクロークするときのコマンド。 |
また、次に示すメソッドがあります。よく使うのは
表: メソッド一覧
メソッド | 説明 |
---|---|
.activate ( index ) | index で示された行を選択する。 |
.curselection() | 選択された行番号の tuple を返す。複数選択可能なとき、値を取り出すのに使う。 |
.delete ( first, last=None ) | first から last までを削除する。 |
.get ( first, last=None ) | first から last までのテキストのタプルを返す。last が指定されていないときは first にある テキストを返す。 |
.index ( i ) | i のインデックスを返す。 |
.insert ( index, *elements ) | index の位置に *elements を挿入する。最後に挿入したときは index を Tk.END とする。 |
.nearest ( y ) | Listbox の上辺を基準とした y 座標に最も近い index を返す。 |
.see ( index ) | index が見えるように位置を調節する。 |
.selection_clear ( first, last=None ) | first から last までの行を選択解除する。 |
.selection_includes ( index ) | index が選択されていれば 1, そうでなければ 0 を返す。 |
.selection_set ( first, last=None ) | first から last までの行を選択する。 |
.size() | 行数を返す。 |
.xview() | 横スクロール可能にする。 |
.xview_moveto ( fraction ) | fraction のところまで横スクロールする。 fraction は 0.0--1.0 の実数。 |
.xview_scroll ( number, what ) | what で示された単位に従って number だけ横スクロールする。 |
.yview() | 縦スクロール可能にする。 |
.yview_moveto ( fraction ) | fraction のところまで縦スクロールする。 fraction は 0.0--1.0 の実数。 |
.yview_scroll( number, what ) | what で示された単位に従って number だけ横スクロールする。 |
Tkinter reference: 11. The Listbox widget および、 The Tkinter Listbox Widget も見てください。
[code 1] (scrolled_listbox.py)
01: #! /usr/bin/env python 02: 03: import Tkinter as Tk 04: 05: class ScrolledListbox(Tk.Listbox): 06: """ Listbox with vertical scroll bar """ 07: 08: def __init__(self, master, **key): 09: self.frame = Tk.Frame(master) 10: self.yscroll = Tk.Scrollbar (self.frame, orient=Tk.VERTICAL) 11: self.yscroll.pack(side=Tk.RIGHT, fill=Tk.Y, expand=1) 12: key['yscrollcommand']=self.yscroll.set 13: Tk.Listbox.__init__(self, self.frame, **key) 14: self.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1) 15: self.yscroll.config(command=self.yview) 16: 17: # Copy geometry methods of self.frame 18: for m in (Tk.Pack.__dict__.keys() + Tk.Grid.__dict__.keys() + Tk.Place.__dict__.keys()): 19: m[0] == '_' or m == 'config' or m == 'configure' or \ 20: setattr(self, m, getattr(self.frame, m))
[code 2] (flower_bg.py)
01: #! /usr/bin/env python 02: # -*- coding: shift_jis -*- 03: """ 04: show_flowers.py 05: 06: Change Background of flower 07: 08: June 28, 2005 09: """ 10: 11: 12: import Tkinter as Tk 13: import scrolled_listbox as SL 14: 15: # thanks to 素材屋ひなとん(http://www.jttk.zaq.ne.jp/bacsn908/) 16: FLOWERS = ["suisencut4.gif", "tanpopotouka1.gif", "odamakitouka.gif", "rengetouka2.gif", \ 17: "ajisaicatmurasaki-a.gif", "cosmos-s.gif", "fujimurasakitouka.gif", "minaesi-5.gif", \ 18: "hotarubukuro3ko.gif", "burudejinarabi.gif", "aoaji3touka.gif", "sakurasou.gif", \ 19: "rengetakusann.gif", "nanohana3.gif", "suzurantouka2.gif", "liradai.gif", \ 20: "cosmostouka-b.gif", "syunrantouka2.gif", "sakuraeda9.gif", "syoubu-s.gif", \ 21: "suirenpink-a.gif", "yuri2.gif", "aoasagaoline.gif", "asagaoyoujiro2.gif", \ 22: "himawari-l.gif", "yagurumagikutouka1.gif", "susukistouka.gif"] 23: 24: 25: BGS = [('aliceblue', '#F0F8FF'), ('azure', '#F0FFFF'), ('beige', '#F5F5DC'), \ 26: ('cornsilk', '#FFF8DC'), ('khaki', '#F0E68C'), ('lightgreen', '#90EE90'), \ 27: ('lightpink', '#FFB6C1'), ('lightskyblue', '#87CEFA'), ('palegreen', '#98FB98')] 28: 29: 30: 31: class BgChange: 32: 33: def __init__(self, label, color): 34: self.label = label 35: self.color = color 36: 37: def __call__(self, event=None): 38: self.label.configure(bg=self.color) 39: 40: 41: class Frame(Tk.Frame): 42: 43: def __init__(self, master=None): 44: Tk.Frame.__init__(self, master) 45: self.master.title('flower image and background') 46: intro = Tk.Label(self, font=('Helvetica', '12'), justify=Tk.LEFT, wraplength='8c', 47: text = u"リストボックスから画像ファイル(マウス左ダブルクリック)、" 48: u"ボタンから背景色を選択してください。" 49: u"左側のラベルに画像が表示されます。") 50: intro.pack() 51: f = Tk.Frame(self, bd=3, relief=Tk.RIDGE) 52: f.pack(fill=Tk.BOTH, expand=1) 53: 54: self.listbox = SL.ScrolledListbox(f) 55: self.listbox.pack(side=Tk.LEFT, padx=5, pady=5, fill=Tk.Y) 56: self.listbox.bind("<Double-Button-1>", self.change_flower) 57: self.listbox.insert(Tk.END, *FLOWERS) 58: 59: f_button = Tk.Frame(f) 60: f_button.pack(side=Tk.LEFT, padx=5, pady=5) 61: self.flower = Tk.PhotoImage(file=FLOWERS[0]) 62: self.label = Tk.Label(f, image=self.flower, relief=Tk.RAISED, bd=3) 63: self.label.pack(side=Tk.RIGHT, padx =5) 64: 65: for name, code in BGS: 66: b = Tk.Button(f_button, text=name, bg=code, command=BgChange(self.label, code)) 67: b.pack(fill=Tk.X) 68: 69: def change_flower(self, event): 70: self.flower = Tk.PhotoImage(file=self.listbox.get(Tk.ACTIVE)) 71: self.label.configure(image=self.flower) 72: 73: 74: ##------------------------------------------------ 75: 76: if __name__ == '__main__': 77: f = Frame() 78: f.pack() 79: f.mainloop()
カッコ内は行番号です。
図1のように花の色と背景色が近い色だときれいに見えます。試してみてください。
[code 2] (flowers.py)
01: #! /usr/bin/env python 02: # -*- coding: shift_jis -*- 03: """ 04: flowers.py 05: 06: Show flower images 07: 08: June 28, 2005 09: """ 10: 11: 12: import Tkinter as Tk 13: import Image as I 14: import ImageTk as Itk 15: import math 16: import scrolled_listbox as SL 17: 18: # thanks to 素材屋ひなとん(http://www.jttk.zaq.ne.jp/bacsn908/) 19: FLOWERS = ["suisencut4.gif", "tanpopotouka1.gif", "odamakitouka.gif", "rengetouka2.gif", \ 20: "ajisaicatmurasaki-a.gif", "cosmos-s.gif", "fujimurasakitouka.gif", "minaesi-5.gif", \ 21: "hotarubukuro3ko.gif", "burudejinarabi.gif", "aoaji3touka.gif", "sakurasou.gif", \ 22: "rengetakusann.gif", "nanohana3.gif", "suzurantouka2.gif", "liradai.gif", \ 23: "cosmostouka-b.gif", "syunrantouka2.gif", "sakuraeda9.gif", "syoubu-s.gif", \ 24: "suirenpink-a.gif", "yuri2.gif", "aoasagaoline.gif", "asagaoyoujiro2.gif", \ 25: "himawari-l.gif", "yagurumagikutouka1.gif", "susukistouka.gif"] 26: 27: 28: SIZE = 100 29: 30: 31: 32: def get_size(tup): 33: """ It returns the size of images on the summary""" 34: x, y = tup 35: if (x<=100 and y<=100): 36: return (x, y) 37: elif x > y: 38: r = float(SIZE) / float(x) 39: return (100, int(y*r)) 40: else: 41: r = float(SIZE) / float(y) 42: return (int(x*r), 100) 43: 44: 45: 46: class Frame(Tk.Frame): 47: 48: def __init__(self, master=None): 49: Tk.Frame.__init__(self, master) 50: self.master.title('show flower images') 51: intro = Tk.Label(self, font=('Helvetica', '12'), justify=Tk.LEFT, wraplength='11c', width=50, 52: text = 53: u"リストボックスから画像ファイルを選択してください。" 54: u"左ボタンのドラッグ、Shift + 左ボタン、Ctrl + 左ボタン などで複数の画像の選択が可能です。\n" 55: u"選択が終わったら、マウス右ボタンをクリックしてください。" 56: u"選択された画像が左側に表示されます。") 57: 58: intro.pack() 59: self.f = Tk.Frame(self, bd=3, relief=Tk.RIDGE) 60: self.f.pack(fill=Tk.BOTH, expand=1) 61: 62: self.listbox = SL.ScrolledListbox(self.f, selectmode=Tk.EXTENDED) 63: self.listbox.pack(side=Tk.LEFT, padx=5, pady=5, fill=Tk.Y) 64: self.listbox.bind("<3>", self.show_flowers) 65: self.listbox.insert(Tk.END, *FLOWERS) 66: 67: self.renew() 68: 69: 70: def show_flowers(self, event): 71: if self.images: 72: self.ff.destroy() 73: self.renew() 74: 75: selected = [ int(x) for x in self.listbox.curselection()] 76: span = int(math.ceil(math.sqrt(len(selected)))) 77: for i, j in enumerate(selected): 78: img = I.open(FLOWERS[j]) 79: img = img.resize(get_size(img.size)) 80: tkimg = Itk.PhotoImage(img) 81: la = Tk.Label(self.ff, image=tkimg) 82: la.grid(row=i/span, column=i%span, sticky=Tk.SW) 83: self.images.append(tkimg) 84: self.listbox.selection_clear(min(selected), max(selected)) 85: 86: 87: def renew(self): 88: self.images = [] 89: self.ff = Tk.Frame(self.f, border=3, relief=Tk.RAISED) 90: self.ff.pack(side=Tk.RIGHT, fill=Tk.BOTH, expand=1, padx =5) 91: 92: 93: ##------------------------------------------------ 94: 95: if __name__ == '__main__': 96: f = Frame() 97: f.pack() 98: f.mainloop() 99:
ここで紹介したスクリプトは [download] からダウンロードできます。 次回は flower_bg.py と flowers.py をもとにして画像ビューアを作ります。次回のプログラムはいろいろな widget を使った 少しは実用的なプログラムです。 いままで、出てきた widget に加えて、 Tk.Entry, Tk.Checkbutton, Tk.Radiobutton, Tk.LabelFrame, Tk.Toplevel, dialog も登場します。
HOME | 5. 関数のクラスを使ってクールなコードを書こう | Python | 7. Widget てんこ盛り画像 Viewer | download | 書き込む |