2013-09-30 10 views
6

aşağıdaki kodu bakın oluşturmak için:Subclassing Tkinter özel bir Widget

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) 
(Temelde Sınıfımdaki tüm yöntemleri/Tkinter.Text işlevleri koruyarak dikey bir kaydırma çubuğu içeren bir metin widget oluşturmak için çalışıyorum)

Özel widget'ımı böyle oluşturmak benim için sorun değil mi, yoksa bir çerçeveye koyup kendi yöntemlerimi yazmalı mıyım?

cevap

2

Alt sınıfın yerini değiştirmek veya güncellemek kolay olabileceğinden, alt sınıfları orta, büyük proje veya gelecekte destekle birlikte kullanacağım. Her durumda alt sınıflandırma maliyetleri düşüktür. Ama göreviniz tek kullanımlık ise, kirli ve hızlı olun.

Bu durumda, çoğu genel pencere öğesi olduğundan ve pack, grid ve diğer yöntemlerin geçersiz kılınması gerekmediğinden Çerçeve'den alt sınıflar kullanacağım.

+0

Ne sormaya çalışıyorum olduğunu Tkinter.Text (ya da yöntem ve işlevleri var korumak için başka widget'ı) özel bir widget oluşturmak için alt sınıfı için iyi bir uygulama öyle. Bu durumda, sınıfımdaki bir kareye bir kaydırma çubuğu yerleştirerek Tkinter.Text alt sınıfını yapıyorum. Veya Çerçeveyi alt sınıflara ayırmalı ve Metin Widget'ını ve kaydırma çubuğunu doğrudan üzerine yerleştirmeli ve kendi yöntemlerimi ve işlevlerimi oluşturmalı mıyım? – user2830098

+0

Cevabın güncellemesine göz atın –

16

Özel bir öğe oluşturmak için bir pencere parçacığını alt sınıflara ayırmak çok normaldir. Ancak, bu özel pencere öğesi birden fazla widget'dan oluşuyorsa normalde Frame alt sınıfını kullanırsınız. Metin eklerken iç metin widget'ı başvurmak gerekir nasıl fark, bu yaklaşımla

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() 

: Örneğin, böyle bir şey yapacağını bir kaydırma çubuğu olan bir metin widget widget oluşturun. Bu widget'ın gerçek bir metin parçacığı gibi daha fazla görünmesini istiyorsanız, metin öğesi işlevlerinin bazılarına veya tümüne bir eşleme oluşturabilirsiniz. Örneğin:

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

Teşekkür ederim, bu gerçekten yardımcı oldu. Oylamayı denedim/cevabınızı kabul ettim, ancak maalesef benim itibarım çok düşük. Başka bir şey, nasıl aynı şekilde bir ttk.Treeview oluşturmak ve bir olaya bağlamak mümkün olacak mı ?, çerçevede treeview örneğini ifşa ve kullanmalı mıyım? – user2830098

+1

Çözümünüzle ilgili sorun, metin üyesi yöntemlerini manuel olarak ortaya çıkarmanız gerektiğinde, OP bunu ücretsiz olarak almayı umuyordu. Bu nedenle, Metin alt sınıflarının orijinal fikrinin gitmenin doğru yolu olduğunu tahmin ediyorum. Tkinter efendimiz konuyu cevaplamak için çok sığ, ama birisi bunu yapabilseydim sevinirim. – quickbug