2016-04-13 52 views
0

Yani, 3 ana alandan oluşan bir pencere olmalıdır küçük bir Python 3 projesi var:Nasıl hep Python 3 diğer Tkinter çerçevelerin üstünde görünür (bir veri giriş formu veya bir durum çubuğu gibi) bir çerçeve yapmak için?

  • Araç çubuğu (üst); Veritabanı veri (ortada) ile
  • Tablo/ağaç - bu tablo kaydırma çubukları ile aşağı doğru büyümek gerekir, ama yine de onları ağaç ile çalışmasını sağlamak için nasıl bilmiyorum;
  • Durum çubuğu (altta).

Ayrıca, kullanıcı talebi konusunda durum çubuğunun hemen üzerinde durması gereken hızlı bir veri giriş formu eklemeye çalışıyorum. Bu pencerenin ana yapısını pack() kullanarak oluşturabildiğimi düşünüyorum. Veri giriş formu, kullanıcı uygun düğmeleri tıkladığında da görünür ve gider. Ama nasıl çözeceğimi bilmediğim birkaç şey var. Birincisi, kullanıcı pencereyi yeniden boyutlandırdığında, daha küçük hale getirdiğinde, durum çubuğu ve veri giriş formunun her ikisi de tablo/ağaç görünümü altında kaybolur. Onları her zaman zirvede nasıl yapabilirim? İşte

benim kodudur:

#!/usr/local/bin/python3 
# encoding: utf-8 

from tkinter import * 
from tkinter import ttk 

entryform_visible = 0 


class mainWindow: 
    def __init__(self, master): 
     self.master = master 
     master.title("AppTittle") 
     master.minsize(width=700, height=200)   

     def show_entryform(): 
      global entryform_visible 
      if entryform_visible == 1: 
       hide_entryform() 
       return 
      else: 
       entryform_visible = 1 
       # Form for data entry (bottom of main window) 
       status_txt.set("Introducing new data...") 
       self.bottomframe.pack(side=BOTTOM, fill=X) 

     def hide_entryform(): 
      global entryform_visible 
      self.bottomframe.pack_forget() 
      entryform_visible = 0 
      status_txt.set("Introduction of data was cancelled.") 

     def add_register(): 
      hide_entryform() 
      status_txt.set("New register added!")     

     # Tool bar (buttons) 
     self.topframe = ttk.Frame(root, padding="3 3 12 12") 
     self.topframe.pack(side=TOP, fill=X) 
     btn_add = ttk.Button(self.topframe, text="Button1").pack(side=LEFT) 
     btn_add = ttk.Button(self.topframe, text="+", width=2, command=show_entryform).pack(side=RIGHT) 
     btn_add = ttk.Button(self.topframe, text="Button2").pack(side=RIGHT) 

     # Data table (center area of window) 
     self.mainframe = ttk.Frame(root) 
     self.mainframe.pack(side=TOP, fill=X) 

     tree = ttk.Treeview(self.mainframe, height=25, selectmode='extended') 
     tree['columns'] = ('id', 'name', 'descr') 
     tree.pack(side=TOP, fill=BOTH) 
     tree.column('#0', anchor=W, minwidth=0, stretch=0, width=0) 
     tree.column('id', anchor=W, minwidth=30, stretch=0, width=40) 
     tree.column('name', minwidth=30, stretch=1, width=30) 
     tree.column('descr', minwidth=100, stretch=1, width=200) 
     tree.heading('id', text="ID") 
     tree.heading('name', text="Name") 
     tree.heading('descr', text="Description") 

     # Data entry form 
     self.bottomframe = ttk.Frame(root, padding="3 3 12 12") 
     ttk.Label(self.bottomframe, text="Field 1").pack(side=LEFT) 
     text_input_obj = ttk.Entry(self.bottomframe, width=13) 
     text_input_obj.pack(side=LEFT) 
     text_input_obj.focus_set() 
     btn_add = ttk.Button(self.bottomframe, text="Add", command=add_register).pack(side=RIGHT) 
     # We are going to pack() this later (when the user clicks the '+' button) 

     # Status bar 
     self.statusframe = ttk.Frame(root, padding="2 2 2 2") 
     self.statusframe.pack(side=BOTTOM, fill=X) 
     status_txt = StringVar() 
     self.statusbar = ttk.Label(self.statusframe, textvariable=status_txt).pack(side=LEFT) 


root = Tk() 
appwindow = mainWindow(root) 
root.mainloop() 
+0

Sanırım bir yolunu buldum. 'Before = self.mainframe' öğesini pack() argümanlarına ekleyebileceğimizi daha yeni keşfettim. Her iki çerçeve için de (durum çubuğu ve form) bunu diğer katmanların üstüne yapıştırırlar. Şimdi benim treeview ile çalışmak için bir kaydırma çubuğu nasıl elde edeceğini öğrenmeliyim ... –

cevap

0

birincisi olduğu kullanıcı bu küçük, durum çubuğu ve veri giriş formu hem tablo altında yok yapma pencere, boyutlandırdığında/ağaç görünümü. Onları her zaman zirvede nasıl yapabilirim?

Bu Packer nasıl çalıştığını ile ilgisi var. Mevcut alan gerekli alandan daha az olduğunda, widget'ları kesmeye başlayacaktır. Widget'ların nasıl paketlendiğini ters sırada yapar.

Bu durumda, alt çerçevenin son olarak paketlenmesi nedeniyle, pencereyi her şeye sığacak kadar küçültmek için küçültürseniz, ilk önce varsayılan boyutlarından daha büyük bir alana genişletmiş olabilecek tüm pencereleri küçültür ve sonra da doğranmaya başlar. paketlenmiş son widget ile başlayan widget'lar. Bu durumda, paketlenecek son ürün olduğundan dolayı kırpılan self.statusframe.

Bunu çözmenin iki yolu vardır. Biri, her şeyi kök penceresine yerleştirdiğiniz sırayı tersine çevirmektir. Diğeri ise başlangıçta ağaç widget'ını çok küçük yapmak ve daha sonra alanı doldurmak için büyümesine izin vermektir. ağaç doğal boyutu küçük olduğu için bu görünümden çıkarmadan widget'lar başlamadan önce, Tkinter bunu küçülecek. Eğer bu ikinci teknik yaparsanız dışarı başladığında, pencere büyük yapmak için wm_geometry kullanabilirsiniz

Benim tavsiyem her zaman grup senin pack ve grid ifadeleri etmektir (Aksi ağaç içine büyümek için herhangi bir boşluk olmayacaktır). Bu şekilde çok kolay değişiklikler yapar ve kodunuzu görselleştirmeyi kolaylaştırır. Örneğin, ilk teknik kullanılarak ben fonksiyonun altına ana alanların paketleme taşımak olacaktır: Bununla

# layout the main GUI 
self.topframe.pack(side=TOP, fill=X) 
self.statusframe.pack(side=BOTTOM, fill=X) 
self.mainframe.pack(side=TOP, fill=BOTH, expand=True) 

, uzay aldığında sıkı paket ağacı kesmek başlayacaktır. Ama ağaç büyük olduğu için, kaybolmaya başlamadan önce doğramak için bol miktarda var.

Bunu yaptığınızda, düzeninizde başka bir sorun ortaya çıkarırsınız ve bu, mainframe numaralı boş alan içinde fazladan boşluk doldurmak için ağaç görünümünün genişletilmemesidir.

tree.pack(side=TOP, fill=BOTH, expand=True) 

Bu başka bir sorun getirir: Bu gibi paketi gerekir. Yani, pop-up pencereniz bottomframe gizlenebilir. Bunun nedeni, paketin bu tür bir durumda iyi çalışması için tasarlanmamış olmasıdır. Yine, pack, eklendikleri ters sırayla widget'ları kesmeye başlayacaktır. En son eklediğinizden, doğranmış olan ilk widget. Kullanıcı pencereyi daha küçük olacak şekilde yeniden boyutlandırırsa, alt kısımda paketlemek, hiç görünmemesine neden olabilir.

Bu özel durumda daha iyi bir çözüm, bu bir widget için değil kullanım paketidir. Bunun yerine, "pop up" olmasını istediğinizden, place'u kullanabilirsiniz. place, diğer widget'ların üstünde widget'ları açmak için mükemmeldir. Elbette

def show_entryform(): 
    ... 
    self.bottomframe.place(relx=.5, rely=1, anchor="s", relwidth=1.0) 
    self.bottomframe.lift() 

Ve place_forget yerine pack_forget kullanın: Yapmanız gereken tek şey, bu çerçeve sen lift ile yapabileceğiniz statusbar, daha yığın sırasında yüksek olduğundan emin olun olduğunu

def hide_entryform(): 
    ... 
    self.bottomframe.place_forget() 
    ... 
+0

Ben o zamandan beri yaptığım bazı değişiklikler ile çok açıklayıcı ipuçlarını birleştirmeye çalışıyorum. Oldukça zor, sanırım. Ancak yeni bir şüphem var. Alt çerçeveyi 'pack' konumundan' place' olarak değiştirdiğimde, her zaman görünmesini istediğim paketlenmiş 'statusframe' üzerine yerleştirilir (pencerenin en altında). 'Paket'e geri dönmeli miyim, yoksa bu çerçeve için bir tür ayarlama ile hala' yer'i tavsiye eder misiniz? “Alt çerçeve” nin “durum çerçevesinin” yukarısında görünmesini sağlamaya çalışıyorum. –

+0

@Victor: İstediğiniz şeyi gerçekleştirmenin birçok yolu vardır. Durum çubuğunda olup olmadığını bilmiyordum. En kolay, oldukça dürüst bir şekilde, 'grid' seçeneğine geçmektir, çünkü 'grid' öğenin orjinal olarak ekrana nasıl eklendiğini hatırladığından widget'ları gizlemek ve geri yüklemek daha kolaydır. Bu söyleniyorsa, pop-up penceresini durum penceresinin (ya da orta pencerenin en altında) üzerine yerleştirmek için 'yer'i kullanabilirsiniz. Belgeleri okuyun - başka bir widget'a göre bir widget yerleştirmek için seçenekler var (in_' seçeneğine bakın. –

+0

"place" kullanarak bunu doğru bir şekilde elde edebildim: self.bottomframe.place (in_ = self.statusframe, relx = 1, y = 0, anchor = "se", relwidth = 1, bordermode = "dış") '.Çok iyi çalışıyor ve önceki 'pack' tabanlı formumla karşılaştırıyor gibi görünüyor. Ekranda "alt çerçeve" görüntülendiğinde gerçekleşen garip bir göz kırpması kurtulmak :) –

İlgili konular