AutoScrollbar (http://effbot.org/zone/tkinter-autoscrollbar.htm) を使用し、水平方向のものも追加しました。
from Tkconstants import VERTICAL, N, S, HORIZONTAL, W, E, END
import Tkinter as Tk
class AutoScrollbar(Tk.Scrollbar):
""" a scrollbar that hides itself if it's not needed. only
works if you use the grid geometry manager."""
def set(self, lo, hi):
if float(lo) <= 0.0 and float(hi) >= 1.0:
# grid_remove is currently missing from Tkinter!
self.tk.call("grid", "remove", self)
else:
self.grid()
Tk.Scrollbar.set(self, lo, hi)
def pack(self, **kw):
raise Tk.TclError, "cannot use pack with this widget"
def place(self, **kw):
raise Tk.TclError, "cannot use place with this widget"
if __name__ == '__main__':
root = Tk.Tk()
scrollbarY = AutoScrollbar(root,orient=VERTICAL)
scrollbarY.grid(column=1, row=0,sticky=N+S)
scrollbarX = AutoScrollbar(root,orient=HORIZONTAL)
scrollbarX.grid(column=0, row=1,sticky=W+E)
mylist = Tk.Listbox(root, xscrollcommand = scrollbarX.set, yscrollcommand = scrollbarY.set )
for line in range(50):
mylist.insert(END, "This is line number " + str(line) + ", and then just for whatever reason this text goes on and on")
mylist.grid(column=0, row=0,sticky=N+S+E+W)
scrollbarX.config( command = mylist.xview )
scrollbarY.config( command = mylist.yview )
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
Tk.mainloop()
今、私は考えました:すべての混乱なしにこの機能を持っているのは素晴らしいことではないでしょうか? そこで、自動非表示スクロールバーを使用して tk.Frame をコーディングすることにしました。アイデアは次のとおりです。Widget を AutoscrollFrame に追加すると、Atuoscrollframe はそのウィジェットを 2x2 グリッドの (0,0) に内部的に配置します。(0,1) と (1,0) は x と y の自動非表示スクロールバーであり、 (1,1) は空白のままです。もちろん、スクロールバーは必要な場合にのみ表示されます。
今では、このアイデアを頭の中で実装するのは非常に簡単に思えました。悲しいことに、そうではないことがすぐにわかりました。「子ウィジェットをフレームに追加」機能を実装するには、どのメソッドをオーバーライドする必要がありますか?
これまでの私のコードは次のようになります。
import Tkinter as tk
from Tkconstants import VERTICAL, N, S, HORIZONTAL, W, E, END
class AutoscrollFrame(tk.Frame):
"""A Frame extension that automatically adds scrollbars
if the content of the frame exceeds it's dimensions.
"""
def __init__(self,master,*args,**kwargs):
self.master = master
super(AutoscrollFrame,self).__init__(master=master,*args,**kwargs)
self.scrollbarY = _AutoScrollbar(self,orient=VERTICAL)
self.scrollbarY.grid(column=1, row=0,sticky=N+S)
self.scrollbarX = _AutoScrollbar(self,orient=HORIZONTAL)
self.scrollbarX.grid(column=0, row=1,sticky=W+E)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
def add_child_placeholder(self,child):
self.child = child
self.child.config(xscrollcommand=scrollbarX.set, yscrollcommand=scrollbarY.set )
self.child.grid(column=0, row=0,sticky=N+S+E+W)
self.scrollbarX.config( command = self.child.xview )
self.scrollbarY.config( command = self.child.yview )
これadd_child_placeholder
は、次のようなことが起こったときに呼び出したいメソッドのプロトタイプです。
frame = AutoscrollFrame(root)
myList = tk.Listbox(frame)
add_child_placeholder
つまり、フレームをマスターとして別のウィジェットに設定した場合、フレームメソッドを呼び出したいとします。これは賢明な方法ですか?これが脳のおならではないかどうかは完全にはわかりませんので、少し助けていただければ幸いです。
PS: この機能を (tk.ListBox ではなく) tk.Frame に追加したかったのは、Listbox が最終的に使用するものかどうかまだわからないからです。