【问题标题】:Frame in canvas will not expand to fit canvas画布中的框架不会扩展以适合画布
【发布时间】:2019-07-14 15:28:27
【问题描述】:

我不确定为什么这不起作用。我一定是遗漏了一些东西,因为我可以使单个框架展开以适合画布,但我无法使框架内的框架展开以适合画布。

我已经为此奋斗了好几个小时,我觉得它很明显。

我希望 NoteFrame 内的标签扩展以填充框架,而 NoteFrame 扩展以填充画布。

这是重现行为代码的最少代码:

import tkinter as tk


class NoteFrame(tk.Frame):
    def __init__(self, container):
        super().__init__(container)
        self.config(background='white')
        for i in range(20):
            tk.Label(self, text='test').grid(row=i, column=0, sticky='nsew')


class GCMain(tk.Tk):
    def __init__(self):
        super().__init__()
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.main_canvas = tk.Canvas(self, background="bisque")
        self.main_canvas.columnconfigure(0, weight=1)
        self.main_canvas.rowconfigure(0, weight=1)
        self.frame_n_canvas = tk.Frame(self.main_canvas)
        self.frame_n_canvas.grid(row=0, column=0, sticky='nsew') # tried with and without this
        self.frame_n_canvas.columnconfigure(0, weight=1)
        self.main_canvas.config(scrollregion=self.main_canvas.bbox("all"), highlightthickness=0)
        scrollbar = tk.Scrollbar(self, orient='vertical')
        scrollbar.grid(row=0, column=1, sticky='nsw')
        scrollbar.config(command=self.main_canvas.yview)
        self.main_canvas.config(yscrollcommand=scrollbar.set)
        self.main_canvas.grid(row=0, column=0, sticky='nsew')
        self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')
        self.main_canvas.bind("<Configure>", self.update_scrollregion)

        nf = NoteFrame(self.frame_n_canvas)
        nf.grid(row=0, column=0, sticky='nsew') # tried with and without this

    def on_resize(self, event):
        w, h = event.width, event.height
        self.main_canvas.configure(width=w, height=h)
        self.frame_n_canvas(width=w, height=h) # tried with and without this

    def update_scrollregion(self, event):
        self.main_canvas.configure(scrollregion=self.main_canvas.bbox("all"))


if __name__ == '__main__':
    GCMain().mainloop()

【问题讨论】:

    标签: python canvas tkinter


    【解决方案1】:

    评论:动态解决方案

    1. 允许您的Label 成为sticky='ew' 使用.grid_columnconfigure(0, weight=1)

      class NoteFrame(tk.Frame):
          def __init__(self, container):
              super().__init__(container)
              self.grid_columnconfigure(0, weight=1)
      
    2. 您需要Canvas(..., window= 对象的iid 项。
      需要参数width=200, height=200

      self.main_canvas.fram_n_canvas_iid =\
              self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')
      
    3. 如已知的那样绑定到"&lt;Configure&gt;

      self.main_canvas.bind("<Configure>", self.canvas_configure)
      
    4. 调整 .frame_n_canvas width.main_canvas width 同步。

      def canvas_configure(self, event):
          canvas = event.widget
          canvas.itemconfigure(canvas.fram_n_canvas_iid, width=canvas.winfo_width())
      


    问题:画布中的框架无法展开以适合画布

    如果在 Canvas 中与 .create_window(... 一起放置,小部件(此处为您的 Frame self.frame_n_canvas)将失去expand 的功能。

    这个,.grid(...,没用,因为您稍后将相同的Frame.create_window(... 放在一起:

    self.frame_n_canvas.grid(row=0, column=0, sticky='nsew') # tried with and without this
    ...
    self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw')
    

    要为您的NoteFrame 提供扩展空间,请使用参数width=200, height=200

    self.main_canvas.create_window(0, 0, window=self.frame_n_canvas, anchor='nw',
                                   width=200, height=200)
    

    要让您的Label 成为sticky='ew',您必须执行.grid_columnconfigure(...

    class NoteFrame(tk.Frame):
        def __init__(self, container):
            super().__init__(container)
            self.grid_columnconfigure(0, weight=1)
    

    结果

    【讨论】:

    • 嘿,stovfl。感谢您的帖子,但我仍然无法使用画布调整框架的大小。向 create_window 选项添加宽度和高度确实会扩展框架,但由于某种原因,我稍后无法调整宽度/高度的大小。我试图直接用框架和 canvas.itemconfig 定义宽度/高度。知道为什么框架没有扩展以完全填满画布吗?
    • @Mike-SMT:更新了我的答案,其中显示了我在问题代码中仅添加.create_window(..., width=200, height=200)self.grid_columnconfigure(0, weight=1) 的结果。请确认这是否是您想要的或解释为什么不这样做。
    • 我还需要框架一直向右展开。填满整个画布。
    • 我在我的问题中添加了更多内容,因为很难在 MCVE 中解释这个问题。如果您还有其他问题,请告诉我。
    • “填充整个画布”:我的固定值 =200 仅用于显示 Label sticky='ew' 正在工作。我假设您想要一个动态解决方案,因此您必须获得 .main_canvas 的大小并相应地调整 item .main_canvas.create_window(... 的大小。
    猜你喜欢
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    相关资源
    最近更新 更多