Python Tkinter的问题:画布中的帧

时间:2011-10-16 20:53:17

标签: python tkinter

我正在尝试设置一组可滚动的Frames,所以我将它们嵌套到Canvas中。下面,我提供了一些演示此问题的示例代码。

但是,我有三个问题:

  1. 框架c似乎没有水平扩展以填充画布。
  2. 如果我使用多个框架c,画布会滚动,但如果我尝试将FrameRow嵌套到单个框架c中,则画布不再滚动。
  3. 使用多个c帧时,FrameRow的最后一个被截断。
  4. 按钮“左”和“右”表示当按钮没有嵌套在画布中时我得到的行为。

    我更喜欢使用单帧c并将所有FrameRows嵌套在其中,但我需要滚动才能正常工作。

    import * from Tkinter
    import FrameRow
    root = Tk()
    root.title("Testing")
    
    containerFrame =  Frame(root)
    containerFrame.config(bg="red")
    containerFrame.pack(side=TOP, fill=BOTH, expand=1)
    
    # Frame showing proper behavior
    a = Frame(containerFrame, bg="black")
    a.pack(side=TOP, fill=X, expand=0)
    
    btnLeft = Button(a)
    btnLeft.config(text="LEFT")
    btnLeft.pack(side=LEFT, fill=X, expand=1)
    
    btnRight = Button(a)
    btnRight.config(text="RIGHT")
    btnRight.pack(side=RIGHT, fill=X, expand=0)
    
    
    # Canvas
    canvas = Canvas(containerFrame)
    scrollbar = Scrollbar(containerFrame, orient=VERTICAL)
    
    scrollbar.config(command=canvas.yview)
    canvas.config(bg="blue", yscrollcommand=scrollbar.set)
    scrollbar.pack(side=RIGHT, fill=Y)
    canvas.pack(side=LEFT, fill=BOTH, expand=1)
    
    # Multiple Frames within Canvas    
    frameRow = range(30)
    c = range(30)
    for r in xrange(0,30):
        c[r] = Frame(canvas)
        c[r].config(bg="green")
    
        frameRow[r] = FrameRow.FrameRow()
        frameRow[r].setFrame(c[r])
        frameRow[r].setRow(r)
        frameRow[r].createRow()
    
        c[r].pack(side=TOP, fill=X, expand=1)
        canvas.create_window(0, (r+1)*30, window=c[r], anchor="nw")
    
    canvas.config(scrollregion = canvas.bbox(ALL))
    
    # OR
    # Single Frame within Canvas
    ##c = Frame(canvas)
    ##c.config(bg="green")
    ##
    ##frameRow = range(30)
    ##for r in xrange(0,30):
    ##    frameRow[r] = FrameRow.FrameRow()
    ##    frameRow[r].setFrame(c)
    ##    frameRow[r].setRow(r)
    ##    frameRow[r].createRow()
    ##
    ##c.pack(side=TOP, fill=X, expand=1)
    ##canvas.create_window(0, 0, window=c, anchor="nw")
    
    root.mainloop()
    

    FrameRow类定义为:

    from Tkinter import *
    
    class FrameRow():
        _frame = "Default"
        _row = 0
    
        def setFrame(self, frame):
            self._frame = frame
    
        def setRow(self, row):
            self._row = row
    
        def createRow(self):
            self.frameRow = Frame(self._frame)
            self.frameRow.config(bg="yellow")
            self.frameRow.pack(side=TOP, fill=X, expand=1)
    
            self.btn1 = Button(self.frameRow)
            self.btn1.config(text="Button "+str(self._row)+"A")
            self.btn1.pack(side=LEFT, fill=X, expand=1)
    
            self.btn2 = Button(self.frameRow)
            self.btn2.config(text="Button "+str(self._row)+"B")
            self.btn2.pack(side=RIGHT, anchor=E, fill=X, expand=0)
    

    在让c扩展到画布的宽度时,是否有一些我缺少的东西?

    滚动和单帧c

    我做错了什么

    是否有任何体面的教程或示例说明我应该如何做到这一点?

    谢谢!

1 个答案:

答案 0 :(得分:1)

看起来你要将窗口打包在画布中并创建一个窗口对象。老实说,我从来没有这样做,但我认为包装没有任何好处。

当您创建作为画布中对象的窗口小部件时,它将展开以填充画布。您需要做的是创建对画布的<Configure>事件的绑定。每当画布改变大小(以及其他几次)时,此事件将触发。然后,您可以调整每个帧的大小以适合画布的宽度。

由于您说您更喜欢使用单个框架将其他行嵌套在其中,这可能是最简单的解决方案。但同样,这个单帧不会增长或缩小以适应画布,你必须使用<Configure>绑定来做到这一点。

确保在使用create_window将画布添加到画布后配置画布的滚动区域。看起来您忘记在注释掉的代码中执行此操作,这肯定会阻止画布滚动。