2013-09-30 16 views
6

次のコードを参照してくださいを作成します。サブクラスTkinterのカスタムウィジェット

class ScrollableTextWidget(Tkinter.Text): 
    def __init__(self, parent): 
     self.parent = parent 
     self.Frame = ttk.Frame(self.parent) 
     Tkinter.Text.__init__(self, self.Frame, width=1, height=1) 
     self.__initWidget() 

    def __initWidget(self): 
     self.Frame.grid(sticky="NSEW") 
     self.ScrollbarY = ttk.Scrollbar(self.Frame, orient="vertical", command=self.yview) 
     self.configure(yscrollcommand=self.ScrollbarY.set) 
     self.grid(column=0, row=0, sticky="NSEW") 
     self.ScrollbarY.grid(column=1, row=0, sticky="NS") 
     self.Frame.columnconfigure(0, weight=1) 
     self.Frame.rowconfigure(0, weight=1) 
(私は基本的に私のクラスのすべてのメソッド/ Tkinter.Textから機能を保持しつつ、垂直スクロールバーでテキストウィジェットを作成しようとしています)

このように私のカスタムウィジェットを作成してもいいですか?それとも、フレームに入れて独自のメソッドを記述する必要がありますか?

答えて

2

サブクラス化は簡単に置き換えたり更新することができるので、私は中、大規模なプロジェクト、または将来サポートが必要なプロジェクトにサブクラスを使用します。いずれにしても、サブクラス化のコストは小さい。 しかし、あなたの仕事が使い捨てであれば、それは汚くて速くなります。

このケースでは、最も一般的なウィジェットであり、オーバーライド不要であるため、フレームからサブクラス化しますpackgridなどのメソッドです。

+0

私が尋ねるのは、カスタムウィジェットを作成するために、Tkinter.Text(またはそのメソッドと関数を保持する他のウィジェット)をサブクラス化することをお勧めしますか?この場合、Tkinter.Textをサブクラス化して、スクロールバーをクラス内のフレームに配置します。または、フレームをサブクラス化して、テキストウィジェットとスクロールバーを直接配置して、独自のメソッドや関数を作成する必要がありますか? – user2830098

+0

私の答えの更新を参照してください –

16

ウィジェットをサブクラス化してカスタムウィジェットを作成するのは非常に普通です。ただし、このカスタムウィジェットが複数のウィジェットで構成されている場合は、通常はサブクラスFrameとなります。テキストを挿入するとき、内部テキストウィジェットを参照する必要がどのように気づく、このアプローチでは

import Tkinter as tk 

class ScrolledText(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent) 
     self.text = tk.Text(self, *args, **kwargs) 
     self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview) 
     self.text.configure(yscrollcommand=self.vsb.set) 
     self.vsb.pack(side="right", fill="y") 
     self.text.pack(side="left", fill="both", expand=True) 

class Example(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.scrolled_text = ScrolledText(self) 
     self.scrolled_text.pack(side="top", fill="both", expand=True) 
     with open(__file__, "r") as f: 
      self.scrolled_text.text.insert("1.0", f.read()) 

root = tk.Tk() 
Example(root).pack(side="top", fill="both", expand=True) 
root.mainloop() 

:たとえば、私はこのような何かをするだろう、スクロールバー付きのテキストウィジェットですウィジェットを作成します。このウィジェットを実際のテキストウィジェットのように見せたい場合は、テキストウィジェット関数の一部またはすべてへのマッピングを作成できます。たとえば、

import Tkinter as tk 

class ScrolledText(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent) 
     self.text = tk.Text(self, *args, **kwargs) 
     self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview) 
     self.text.configure(yscrollcommand=self.vsb.set) 
     self.vsb.pack(side="right", fill="y") 
     self.text.pack(side="left", fill="both", expand=True) 

     # expose some text methods as methods on this object 
     self.insert = self.text.insert 
     self.delete = self.text.delete 
     self.mark_set = self.text.mark_set 
     self.get = self.text.get 
     self.index = self.text.index 
     self.search = self.text.search 

class Example(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.scrolled_text = ScrolledText(self) 
     self.scrolled_text.pack(side="top", fill="both", expand=True) 
     with open(__file__, "r") as f: 
      self.scrolled_text.insert("1.0", f.read()) 

root = tk.Tk() 
Example(root).pack(side="top", fill="both", expand=True) 
root.mainloop() 
+0

ありがとう、本当に役立った。私はあなたの答えを受け入れるよう投票しようとしましたが、残念ながら私の評判は低すぎます。もう1つの方法は、同じ方法でttk.Treeviewを作成し、そのイベントをバインドできるようにするにはどうすればよいですか?フレーム内のツリービューインスタンスを公開して使用する必要がありますか? – user2830098

+1

あなたのソリューションの問題は、テキスト・メンバー・メソッドを手動で公開しなければならないということです.OPはこれを無料で入手することを望んでいました。したがって、私は、Textをサブクラス化する彼の元の考え方が正しい方法であったと推測します。私のTkinterのマスタリングは問題に答えるには浅すぎますが、誰かがそうすることができたらうれしいです。 – quickbug

関連する問題