Tkinter画布未填充根窗口

0 投票
1 回答
1015 浏览
提问于 2025-04-18 17:30

下面的代码创建了一个画布,里面有一个框架。我使用这个画布是为了添加一个垂直的滚动条,滚动条会根据需要出现。我给不同的部分上了颜色 - 根部分是蓝色;窗口是绿色;画布是红色;框架是青色。从这些颜色可以看出,窗口完全填满了根部分(看不到蓝色)。但是,画布只在垂直方向上填满了窗口(在窗口扩展时,右边可以看到绿色),而框架只在水平方向上填满了画布(在青色下面可以看到红色)。我看不出是什么导致了这个问题。框架是绑定在画布上的,而画布设置了sticky='nsew',所以应该填满窗口。

import Tkinter as tk
import tkFileDialog

class AutoScrollbar(tk.Scrollbar):
    # a scrollbar that hides itself if it's not needed.  only
    # works if you use the grid geometry manager.
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        tk.Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"

class Window(tk.Frame):
  def UserInput(self,status,name):
    row = self.row
    optionLabel = tk.Label(self.frame)
    optionLabel["text"] = name
    optionLabel.grid(row=row, column=0, sticky='w')
    var = tk.StringVar(root)
    var.set(status)
    w = tk.Entry(self.frame, textvariable= var)
    w.grid(row=row, column=1, sticky='ew')
    self.grid_columnconfigure(1,weight=1)
    self.row += 1
    return w

  def on_canvas_resize(self,event):
    padding = 8
    width = self.canvas.winfo_width() - padding
    self.canvas.itemconfigure("frame", width=width)

  def OnFrameConfigure(self, event):
    self.canvas.configure(scrollregion=self.canvas.bbox("all"))

  def __init__(self,parent):
    tk.Frame.__init__(self,parent)

    self.grid_rowconfigure(0, weight=1)
    self.grid_columnconfigure(0,weight=1)

    self.vscrollbar = AutoScrollbar(self,orient = tk.VERTICAL)
    self.vscrollbar.grid(row = 0,column = 3, sticky = 'ns')

    self.canvas = tk.Canvas(self, yscrollcommand = self.vscrollbar.set,bg='red')
    self.canvas.grid(row=0, column=0, sticky='nsew')
    self.canvas.grid_rowconfigure(0, weight = 1)
    self.canvas.grid_columnconfigure(0, weight = 1)

    self.frame = tk.Frame(self.canvas, bg='cyan')
    self.frame.bind("<Configure>", self.OnFrameConfigure)

    self.frame.grid_rowconfigure(0, weight=1)
    self.frame.grid_columnconfigure(0,weight=1)
    self.frame.grid_columnconfigure(1,weight=3)

    self.vscrollbar.config(command=self.canvas.yview) 

    self.canvas.create_window(0, 0, anchor = tk.NW, window= self.frame, tags =["frame"])
    self.canvas.bind("<Configure>", self.on_canvas_resize)

    self.row = 0

    for i in range(10):
      self.Number = self.UserInput("1", "number")

if __name__ == "__main__":
  root = tk.Tk()
  root.configure(background='blue')  
  root.grid_columnconfigure(0, weight=1)
  root.grid_rowconfigure(0,weight=1)  
  window = Window(root)
  window.configure(background='green')
  window.grid(row=0,column=0,sticky='nsew')
  root.mainloop()

1 个回答

1

你把画布放在了第0列,并且给这列设置了合适的权重。不过,你同时也给第1列设置了相同的权重(见第29行),这就导致画布无法填满整个窗口。你需要去掉第29行,也就是把第1列的权重设置去掉。

你的框架在水平方向上填满了画布,因为你就是这么设置的。如果你想让它的高度也一样,你还需要设置它的高度。

撰写回答