2013-10-08 71 views
1

我已經有一個簡單的GUI,它在顯示初始選項的數目之後向用戶顯示一些選項。在這種情況下,4:使用Tkinter(Python)將滾動條添加到框架

initial

通過點擊Add row你可以添加一行到GUI。問題是,如果用戶需要100個選項,GUI會變得特別大,並且所有選項都不會顯示。 big

所以我想只在選項空間上有一個滾動條,而不是其餘部分。很抱歉的壞的Photoshop,但我想有這樣的事情: desiredsolution

的選擇空間是FrameTwo,所以我想有整個FrameTwo像上面的圖片滾動條的內部。

# -*- coding: utf-8 -*- 
from Tkinter import * 
import Image 
import ImageTk 
import tkFileDialog 
import datetime 

class Planificador(Frame): 
    def __init__(self,master): 
     Frame.__init__(self, master) 
     self.master = master 
     self.initUI() 

    def initUI(self): 
     self.master.title("Plan") 
     self.frameOne = Frame(self.master) 
     self.frameOne.grid(row=0,column=0) 
     self.frameTwo = Frame(self.master) 
     self.frameTwo.grid(row=1, column=0) 
     self.frameThree = Frame(self.master) 
     self.frameThree.grid(row=2, column=0) 

     # Borrar esto? 
     self.txt = Text(self) 
     self.txt.pack(fill=BOTH, expand=1) 

     self.piezastext = Label(self.frameOne, text = " Amount of pieces ", justify="center") 
     self.piezastext.grid(row=1, column=0) 
     self.entrypiezas = Entry(self.frameOne,width=3) 
     self.entrypiezas.grid(row=2, column=0, pady=(5,5)) 
     self.aceptarnumpiezas = Button(self.frameOne,text="Click me", command=self.aceptar_piezas,width=8) 
     self.aceptarnumpiezas.grid(row=6, column=0, pady=(5,5)) 

    def aceptar_piezas(self): 
     try: 
      val = int(self.entrypiezas.get()) 
      self.aceptar_piezas_ok() 
     except ValueError: 
      showerror('Error', "Introduce un numero") 

    def aceptar_piezas_ok(self): 
     self.num_piezas = self.entrypiezas.get() 

     self.piezastext.grid_remove() 
     self.entrypiezas.grid_remove() 
     self.aceptarnumpiezas.grid_remove() 

     self.optionmenus_piezas = list() 
     self.numpiezas = [] 
     self.numerolotes = [] 
     self.optionmenus_prioridad = list() 
     self.lotes = list() 

     self.mispiezas = ['One', 'Two', 'Three', 'Four', 'Five'] 

     self.n = 1 
     while self.n <= int(self.num_piezas): 
      self.textopieza = Label(self.frameTwo, text = "Pieza: ", justify="left") 
      self.textopieza.grid(row=self.n, column=0) 

      var = StringVar() 
      menu = OptionMenu(self.frameTwo, var, *self.mispiezas) 
      menu.config(width=10) 
      menu.grid(row=self.n, column=1) 
      var.set("One") 
      self.optionmenus_piezas.append((menu, var)) 

      self.numpiezastext = Label(self.frameTwo, text = "Numero de piezas: ", justify="center") 
      self.numpiezastext.grid(row=self.n, column=2, padx=(10,0)) 
      self.entrynumpiezas = Entry(self.frameTwo,width=6) 
      self.entrynumpiezas.grid(row=self.n, column=3, padx=(0,10)) 
      self.entrynumpiezas.insert(0, "0") 

      self.textoprioridad = Label(self.frameTwo, text = "Prioridad: ", justify="center") 
      self.textoprioridad.grid(row=self.n, column=4) 
      var2 = StringVar() 
      menu2 = OptionMenu(self.frameTwo, var2, "Normal", "Baja", "Primera pieza", "Esta semana") 
      menu2.config(width=10) 
      menu2.grid(row=self.n, column=5) 
      var2.set("Normal") 
      self.optionmenus_prioridad.append((menu2, var2)) 

      self.lotestext = Label(self.frameTwo, text = "Por lotes?", justify="center") 
      self.lotestext.grid(row=self.n, column=6, padx=(10,0)) 
      self.var1 = IntVar() 
      self.entrynumlotes = Checkbutton(self.frameTwo, variable=self.var1) 
      self.entrynumlotes.grid(row=self.n, column=7, padx=(5,10)) 
      self.lotes.append(self.var1) 
      self.numpiezas.append(self.entrynumpiezas) 

      self.n += 1 

     self.anadirpiezas = Button(self.frameThree, text="Add row", command=self.addpieza, width=10) 
     self.anadirpiezas.grid(row=0, column=2, pady=(10,10)) 

     self.calculotext = Label(self.frameThree, text = "Other stuff ") 
     self.calculotext.grid(row=1, column=2, padx=(10,0), pady=(10,10)) 

     self.graspbutton = Button(self.frameThree, text="OPT 1", width=10) 
     self.graspbutton.grid(row=2, column=1) 

     self.parettobutton = Button(self.frameThree, text="OPT 2",width=10) 
     self.parettobutton.grid(row=2, column=2, pady=(10,10), padx=(10,0)) 

     self.parettoEvolbutton = Button(self.frameThree, text="OPT 2", width=10) 
     self.parettoEvolbutton.grid(row=2, column=3, pady=(10,10), padx=(10,0)) 


    def addpieza(self): 
      self.textopiezanuevo = Label(self.frameTwo, text = "Pieza: ", justify="left") 
      self.textopiezanuevo.grid(row=int(self.num_piezas)+1, column=0) 

      var = StringVar() 
      menu = OptionMenu(self.frameTwo, var, *self.mispiezas) 
      menu.grid(row=self.n, column=1) 
      menu.config(width=10) 
      menu.grid(row=int(self.num_piezas)+1, column=1) 
      var.set("One") 
      self.optionmenus_piezas.append((menu, var)) 

      self.numpiezastext = Label(self.frameTwo, text = "Numero de piezas: ", justify="center") 
      self.numpiezastext.grid(row=int(self.num_piezas)+1, column=2, padx=(10,0)) 
      self.entrynumpiezas = Entry(self.frameTwo,width=6) 
      self.entrynumpiezas.grid(row=int(self.num_piezas)+1, column=3, padx=(0,10)) 
      self.entrynumpiezas.insert(0, "0") 

      self.textoprioridad = Label(self.frameTwo, text = "Prioridad: ", justify="center") 
      self.textoprioridad.grid(row=int(self.num_piezas)+1, column=4) 
      var2 = StringVar() 
      menu2 = OptionMenu(self.frameTwo, var2, "Normal", "Baja", "Primera pieza", "Esta semana") 
      menu2.config(width=10) 
      menu2.grid(row=int(self.num_piezas)+1, column=5) 
      var2.set("Normal") 
      self.optionmenus_prioridad.append((menu2, var2)) 

      self.lotestext = Label(self.frameTwo, text = "Por lotes?", justify="center") 
      self.lotestext.grid(row=int(self.num_piezas)+1, column=6, padx=(10,0)) 
      self.var1 = IntVar() 
      self.entrynumlotes = Checkbutton(self.frameTwo, variable=self.var1) 
      self.entrynumlotes.grid(row=int(self.num_piezas)+1, column=7, padx=(5,10)) 
      self.lotes.append(self.var1) 

      self.numpiezas.append(self.entrynumpiezas) 
      self.num_piezas = int(self.num_piezas)+1 

if __name__ == "__main__": 
    root = Tk() 
    aplicacion = Planificador(root) 
    root.mainloop() 

FrameOne是用來放圖片我刪除,以使這個例子更簡單。並且FrameThree是您可以在GUI底部看到的按鈕。

因此,如果有人可以幫我一個忙,並告訴我如何將整個FrameTwo放在滾動條的內部,就像您在第三張圖片上看到的一樣,這將非常有幫助。

在此先感謝。

+0

當我看到有沒有anwers,我想知道是否有可能建立一個固定大小的接口中,例如500x400和放整個事情的滾動條。謝謝。 –

回答

-4

您在FrameTwo中有選項菜單,標籤,輸入框和檢查按鈕。您如何期望整個框架的滾動條可以工作?它會同時滾動所有小部件嗎? Tkinter滾動條通常附加到列表框,畫布,條目窗口小部件和文本字段。 http://effbot.org/zone/tkinter-scrollbar-patterns.htm拿出一個簡單的例子來說明問題的進一步幫助。

+1

這不是一個答案,它是一個評論和驗證請求。 –

1

你的問題之一是,「frameTwo」對它的大小沒有限制。如果你不限制它的大小,你添加的任何滾動條都不會起作用。但限制你的框架的大小有限制你可以網格線的數量,使滾動條無用的麻煩。

解決方案是在「frameTwo」內創建一個框架,以接收您創建的作品。這樣,一方面,您可以限制「frameTwo」的大小並將滾動條附加到它上面,另一方面,允許您將添加到位於「frameTwo」內的框架中的部分網格化,名爲,讓我們假設,「ListFrame」。當「ListFrame」尺寸變得比「frameTwo」尺寸大時,現在可以使滾動條工作。

我使用上面提到的更改更改您的代碼。一探究竟。 更改在代碼中註釋。 對不起,簡單的解釋,但我有點匆忙。我有更多時間可以編輯這個答案。

PS:很抱歉,如果我的英語不是最好的

# -*- coding: utf-8 -*- 
from Tkinter import * 
import Image 
import ImageTk 
import tkFileDialog 
import datetime 

class Planificador(Frame): 
    def __init__(self,master): 
     Frame.__init__(self, master) 
     self.master = master 
     self.initUI() 

    def initUI(self): 
     self.master.title("Plan") 
     self.frameOne = Frame(self.master) 
     self.frameOne.grid(row=0,column=0) 

     self.frameTwo = Frame(self.master) 
     self.frameTwo.grid(row=1, column=0) 

     #Creating of a new frame, inside of "frameTwo" to the objects to be inserted 
     #Creating a scrollbar 

     #The reason for this, is to attach the scrollbar to "FrameTwo", and when the size of frame "ListFrame" exceed the size of frameTwo, the scrollbar acts 
     self.canvas=Canvas(self.frameTwo) 
     self.listFrame=Frame(self.canvas) 
     self.scrollb=Scrollbar(self.master, orient="vertical",command=self.canvas.yview) 
     self.scrollb.grid(row=1, column=1, sticky='nsew') #grid scrollbar in master, but 
     self.canvas['yscrollcommand'] = self.scrollb.set #attach scrollbar to frameTwo 

     self.canvas.create_window((0,0),window=self.listFrame,anchor='nw') 
     self.listFrame.bind("<Configure>", self.AuxscrollFunction) 
     self.scrollb.grid_forget()       #Forget scrollbar because the number of pieces remains undefined by the user. But this not destroy it. It will be "remembered" later. 

     self.canvas.pack(side="left") 
     self.frameThree = Frame(self.master) 
     self.frameThree.grid(row=2, column=0) 

     # Borrar esto? 
     self.txt = Text(self) 
     self.txt.pack(fill=BOTH, expand=1) 

     self.piezastext = Label(self.frameOne, text = " Amount of pieces ", justify="center") 
     self.piezastext.grid(row=1, column=0) 
     self.entrypiezas = Entry(self.frameOne,width=3) 
     self.entrypiezas.grid(row=2, column=0, pady=(5,5)) 
     self.aceptarnumpiezas = Button(self.frameOne,text="Click me", command=self.aceptar_piezas,width=8) 
     self.aceptarnumpiezas.grid(row=6, column=0, pady=(5,5)) 

    def AuxscrollFunction(self,event): 
     #You need to set a max size for frameTwo. Otherwise, it will grow as needed, and scrollbar do not act 
     self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=600,height=500) 

    def aceptar_piezas(self): 



     #IMPORTANT!!! All the objects are now created in "ListFrame" and not in "frameTwo" 
     #I perform the alterations. Check it out 
     try: 
      val = int(self.entrypiezas.get()) 
      self.aceptar_piezas_ok() 
      self.scrollb.grid(row=1, column=1, sticky='nsew') #grid scrollbar in master, because user had defined the numer of pieces 
     except ValueError: 
      showerror('Error', "Introduce un numero") 

    def aceptar_piezas_ok(self): 
     self.num_piezas = self.entrypiezas.get() 

     self.piezastext.grid_remove() 
     self.entrypiezas.grid_remove() 
     self.aceptarnumpiezas.grid_remove() 

     self.optionmenus_piezas = list() 
     self.numpiezas = [] 
     self.numerolotes = [] 
     self.optionmenus_prioridad = list() 
     self.lotes = list() 

     self.mispiezas = ['One', 'Two', 'Three', 'Four', 'Five'] 

     self.n = 1 
     while self.n <= int(self.num_piezas): 
      self.textopieza = Label(self.listFrame, text = "Pieza: ", justify="left") 
      self.textopieza.grid(row=self.n, column=0) 

      var = StringVar() 
      menu = OptionMenu(self.listFrame, var, *self.mispiezas) 
      menu.config(width=10) 
      menu.grid(row=self.n, column=1) 
      var.set("One") 
      self.optionmenus_piezas.append((menu, var)) 

      self.numpiezastext = Label(self.listFrame, text = "Numero de piezas: ", justify="center") 
      self.numpiezastext.grid(row=self.n, column=2, padx=(10,0)) 
      self.entrynumpiezas = Entry(self.listFrame,width=6) 
      self.entrynumpiezas.grid(row=self.n, column=3, padx=(0,10)) 
      self.entrynumpiezas.insert(0, "0") 

      self.textoprioridad = Label(self.listFrame, text = "Prioridad: ", justify="center") 
      self.textoprioridad.grid(row=self.n, column=4) 
      var2 = StringVar() 
      menu2 = OptionMenu(self.listFrame, var2, "Normal", "Baja", "Primera pieza", "Esta semana") 
      menu2.config(width=10) 
      menu2.grid(row=self.n, column=5) 
      var2.set("Normal") 
      self.optionmenus_prioridad.append((menu2, var2)) 

      self.lotestext = Label(self.listFrame, text = "Por lotes?", justify="center") 
      self.lotestext.grid(row=self.n, column=6, padx=(10,0)) 
      self.var1 = IntVar() 
      self.entrynumlotes = Checkbutton(self.listFrame, variable=self.var1) 
      self.entrynumlotes.grid(row=self.n, column=7, padx=(5,10)) 
      self.lotes.append(self.var1) 
      self.numpiezas.append(self.entrynumpiezas) 

      self.n += 1 

     self.anadirpiezas = Button(self.frameThree, text="Add row", command=self.addpieza, width=10) 
     self.anadirpiezas.grid(row=0, column=2, pady=(10,10)) 

     self.calculotext = Label(self.frameThree, text = "Other stuff ") 
     self.calculotext.grid(row=1, column=2, padx=(10,0), pady=(10,10)) 

     self.graspbutton = Button(self.frameThree, text="OPT 1", width=10) 
     self.graspbutton.grid(row=2, column=1) 

     self.parettobutton = Button(self.frameThree, text="OPT 2",width=10) 
     self.parettobutton.grid(row=2, column=2, pady=(10,10), padx=(10,0)) 

     self.parettoEvolbutton = Button(self.frameThree, text="OPT 2", width=10) 
     self.parettoEvolbutton.grid(row=2, column=3, pady=(10,10), padx=(10,0)) 


    def addpieza(self): 
      self.textopiezanuevo = Label(self.listFrame, text = "Pieza: ", justify="left") 
      self.textopiezanuevo.grid(row=int(self.num_piezas)+1, column=0) 

      var = StringVar() 
      menu = OptionMenu(self.listFrame, var, *self.mispiezas) 
      menu.grid(row=self.n, column=1) 
      menu.config(width=10) 
      menu.grid(row=int(self.num_piezas)+1, column=1) 
      var.set("One") 
      self.optionmenus_piezas.append((menu, var)) 

      self.numpiezastext = Label(self.listFrame, text = "Numero de piezas: ", justify="center") 
      self.numpiezastext.grid(row=int(self.num_piezas)+1, column=2, padx=(10,0)) 
      self.entrynumpiezas = Entry(self.listFrame,width=6) 
      self.entrynumpiezas.grid(row=int(self.num_piezas)+1, column=3, padx=(0,10)) 
      self.entrynumpiezas.insert(0, "0") 

      self.textoprioridad = Label(self.listFrame, text = "Prioridad: ", justify="center") 
      self.textoprioridad.grid(row=int(self.num_piezas)+1, column=4) 
      var2 = StringVar() 
      menu2 = OptionMenu(self.listFrame, var2, "Normal", "Baja", "Primera pieza", "Esta semana") 
      menu2.config(width=10) 
      menu2.grid(row=int(self.num_piezas)+1, column=5) 
      var2.set("Normal") 
      self.optionmenus_prioridad.append((menu2, var2)) 

      self.lotestext = Label(self.listFrame, text = "Por lotes?", justify="center") 
      self.lotestext.grid(row=int(self.num_piezas)+1, column=6, padx=(10,0)) 
      self.var1 = IntVar() 
      self.entrynumlotes = Checkbutton(self.listFrame, variable=self.var1) 
      self.entrynumlotes.grid(row=int(self.num_piezas)+1, column=7, padx=(5,10)) 
      self.lotes.append(self.var1) 

      self.numpiezas.append(self.entrynumpiezas) 
      self.num_piezas = int(self.num_piezas)+1 

if __name__ == "__main__": 
    root = Tk() 
    aplicacion = Planificador(root) 
    root.mainloop()