2013-10-08 66 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()