
在 Tkinter 中,为 Frame 添加滚动条需要结合 Canvas(画布)和 Scrollbar(滚动条)来实现,因为 Frame 本身不支持滚动。以下是一个完整的示例,展示如何在 Tkinter 中创建一个带有滚动条的 Frame。
1、问题背景
我有一个简单的GUI,在显示一些选项给用户之前,让用户输入选项的初始数量。在本例中,为 4:
点击 Add row 可以向 GUI 添加一行。问题是如果用户想添加 100 个选项,GUI 就会变得非常大,并且无法显示所有选项。
因此,我想仅在选项空间上有一个滚动条,而不是其他部分。抱歉,图片不是很清晰,但我想要类似这样的东西:
选项空间是 FrameTwo,因此我想让整个 FrameTwo 都在滚动条中,如上图所示。
2、解决方案
要为 FrameTwo 添加滚动条,您可以使用以下步骤:
以下是一个示例代码,演示了如何实现此操作:
import tkinter as tk
class Planificador(tk.Frame):
    def __init__(self,master):
        tk.Frame.__init__(self, master)
        self.master = master
        self.initUI()
    def initUI(self):
        self.master.title("Plan")
        self.frameOne = tk.Frame(self.master)
        self.frameOne.grid(row=0,column=0)
        self.frameTwo = tk.Frame(self.master)
        self.frameTwo.grid(row=1, column=0)
        # 创建新的Frame
        self.listFrame = tk.Frame(self.frameTwo)
        # 创建Canvas
        self.canvas=tk.Canvas(self.frameTwo)
        # 将ListFrame添加到Canvas中
        self.canvas.create_window((0,0),window=self.listFrame,anchor='nw')
        # 为frameTwo创建滚动条
        self.scrollb=tk.Scrollbar(self.master, orient="vertical",command=self.canvas.yview)
        # 将滚动条与frameTwo关联
        self.canvas['yscrollcommand'] = self.scrollb.set
        # 将canvas与滚动条添加到frameTwo中
        self.canvas.pack(side="left")
        self.scrollb.pack(side="left", fill="y")
        self.frameThree = tk.Frame(self.master)
        self.frameThree.grid(row=2, column=0)
        # 创建一些控件,这些控件将添加到 ListFrame 中
        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 <= 4:
            self.textopieza = tk.Label(self.listFrame, text = "Pieza: ", justify="left")
            self.textopieza.grid(row=self.n, column=0)
            var = tk.StringVar()
            menu = tk.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 = tk.Label(self.listFrame, text = "Numero de piezas: ", justify="center")
            self.numpiezastext.grid(row=self.n, column=2, padx=(10,0))
            self.entrynumpiezas = tk.Entry(self.listFrame,width=6)
            self.entrynumpiezas.grid(row=self.n, column=3, padx=(0,10))
            self.entrynumpiezas.insert(0, "0")
            self.textoprioridad = tk.Label(self.listFrame, text = "Prioridad: ", justify="center")
            self.textoprioridad.grid(row=self.n, column=4)
            var2 = tk.StringVar()
            menu2 = tk.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 = tk.Label(self.listFrame, text = "Por lotes?", justify="center")
            self.lotestext.grid(row=self.n, column=6, padx=(10,0))
            self.var1 = tk.IntVar()
            self.entrynumlotes = tk.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 = tk.Button(self.frameThree, text="Add row", command=self.addpieza, width=10)
        self.anadirpiezas.grid(row=0, column=2, pady=(10,10))
        self.calculotext = tk.Label(self.frameThree, text = "Other stuff ")
        self.calculotext.grid(row=1, column=2, padx=(10,0), pady=(10,10))
        self.graspbutton = tk.Button(self.frameThree, text="OPT 1", width=10)
        self.graspbutton.grid(row=2, column=1)
        self.parettobutton = tk.Button(self.frameThree, text="OPT 2",width=10)
        self.parettobutton.grid(row=2, column=2, pady=(10,10), padx=(10,0))
        self.parettoEvolbutton = tk.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 = tk.Label(self.listFrame, text = "Pieza: ", justify="left")
            self.textopiezanuevo.grid(row=int(self.num_piezas)+1, column=0)
            var = tk.StringVar()
            menu = tk.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 = tk.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 = tk.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 = tk.Label(self.listFrame, text = "Prioridad: ", justify="center")
            self.textoprioridad.grid(row=int(self.num_piezas)+1, column=4)
            var2 = tk.StringVar()
            menu2 = tk.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,这个方法是 Tkinter 实现可滚动 Frame 的标准做法,希望对你有帮助!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。