【问题标题】:tkinter label inside frame of frame框架框架内的 tkinter 标签
【发布时间】:2021-11-13 17:11:00
【问题描述】:

我现在正在练习框架设置在 tkinter 中的动态性。

对于纯框架设置,它看起来很完美:

import tkinter as tk

class MyWindow: 
    def __init__(self, root):
        
        w_root = 1280
        h_root = 720
        root.title('My model')
        root.geometry(f"{w_root}x{h_root}")
        
        self.top_frame = tk.Frame(root, width=w_root, height=80, bg='grey')
        self.top_frame.grid(row=0, column=0, padx=0, pady=5)
        self.main_frame = tk.Frame(root, width=w_root, height=640, bg='blue')
        self.main_frame.grid(row=1, column=0, padx=0, pady=0) 
        self.left_frame = tk.Frame(self.main_frame, width=500, height=620, bg='red')
        self.left_frame.grid(row=0, column=0, padx=5, pady=5)       
        self.right_frame = tk.Frame(self.main_frame, width=760, height=620, bg='yellow')
        self.right_frame.grid(row=0, column=1, padx=5, pady=5)
          

root = tk.Tk()
mywin = MyWindow(root)
root.mainloop()

但是,当我尝试在left_frame(主框架内的框架)中放置标签时,界面变得奇怪:

import tkinter as tk

class MyWindow: 
    def __init__(self, root):
        
        w_root = 1280
        h_root = 720
        root.title('My model')
        root.geometry(f"{w_root}x{h_root}")
        
        self.top_frame = tk.Frame(root, width=w_root, height=80, bg='grey')
        self.top_frame.grid(row=0, column=0, padx=0, pady=5)
        self.main_frame = tk.Frame(root, width=w_root, height=640, bg='blue')
        self.main_frame.grid(row=1, column=0, padx=0, pady=0) 
        self.left_frame = tk.Frame(self.main_frame, width=500, height=620, bg='red')
        self.left_frame.grid(row=0, column=0, padx=5, pady=5)       
        self.right_frame = tk.Frame(self.main_frame, width=760, height=620, bg='yellow')
        self.right_frame.grid(row=0, column=1, padx=5, pady=5)
        
        
        self.lb_currdate = tk.Label(self.left_frame, text='my lable1:')
        self.lb_currdate.config(font=('Arial', 9))
        self.lb_currdate.grid(row=0,column=0, padx=5, pady=5)
        
        self.ent_currdate = tk.Entry(self.left_frame)
        self.ent_currdate.insert(tk.END, str(0))
        self.ent_currdate.grid(row=0,column=1, padx=5, pady=5)

root = tk.Tk()
mywin = MyWindow(root)
root.mainloop() 

我希望框架看起来相同,并且标签和条目将在红色框架(左框架)的顶部移动。

我对此感到很困惑,有人可以提示我哪一行代码是错误的吗?

谢谢

#-----更新-----

根据建议,我在网格中加入了粘性。 它看起来好多了,但仍然没有达到我预期的 100%。我尝试了不同的粘性组合,但没有一个是正确的:

Test1(给左框架粘性)

self.left_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)

大型机没有填满 enti

Test2(让左框架和主框架都具有粘性)

self.main_frame.grid(row=1, column=0, padx=0, pady=0, sticky=tk.N + tk.E + tk.S + tk.W)

self.left_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)

左边框和右边框没有填满主边框

【问题讨论】:

  • sticky 选项是告诉布局管理器如何占用一行或一列的可用空间。但是,您需要使用.rowconfigure().columnconfigure() 告诉布局管理器要为列或行分配多少空间

标签: python tkinter


【解决方案1】:

使红框展开以填充其网格单元格

问题在于框架会自动调整大小以适应内容。要解决此问题,您可以使用 grid 方法的 sticky 关键字参数。

self.left_frame.grid(row=0, column=0, padx=5, pady=5, sticky='NESW')

'NESW' 代表“北、东、南、西”。如果你愿意,你可以这样写:

self.left_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)

您需要对每个想要表现得像这样的帧都执行此操作。

您还可以使用不同的粘性值来产生不同的结果,例如如果您只使用sticky=tk.S,那么框架将移动到其可用空间的底部。

删除不需要的空白空间

为了使框架填充空间,您可以使用 grid_rowconfiguregrid_columnconfigureweight 关键字参数。有关完整说明,请参阅 here

简而言之,您需要将网格配置为扩展以填充可用空间,而不是手动指定宽度和高度。我已经修改了你的代码来做到这一点。请注意,唯一以像素为单位指定高度的时间是当框架不应该扩展时,即top_frame

import tkinter as tk


class MyWindow:
    def __init__(self, root: tk.Tk):
        w_root = 1280
        h_root = 720
        root.title('My model')
        root.geometry(f"{w_root}x{h_root}")

        self.top_frame = tk.Frame(root, height=80, bg='grey')
        self.top_frame.grid(row=0, column=0, padx=0, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)
        self.main_frame = tk.Frame(root, bg='blue')
        root.grid_rowconfigure(1, weight=1)
        root.grid_columnconfigure(0, weight=1)

        self.main_frame.grid(row=1, column=0, padx=0, pady=0, sticky=tk.N + tk.E + tk.S + tk.W)
        self.main_frame.grid_rowconfigure(0, weight=1)

        self.left_frame = tk.Frame(self.main_frame, bg='red')
        self.left_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)
        self.main_frame.grid_columnconfigure(0, weight=1)

        self.right_frame = tk.Frame(self.main_frame, bg='yellow')
        self.right_frame.grid(row=0, column=1, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)
        self.main_frame.grid_columnconfigure(1, weight=2)

        self.lb_currdate = tk.Label(self.left_frame, text='my lable1:')
        self.lb_currdate.config(font=('Arial', 9))
        self.lb_currdate.grid(row=0, column=0, padx=5, pady=5)

        self.ent_currdate = tk.Entry(self.left_frame)
        self.ent_currdate.insert(tk.END, str(0))
        self.ent_currdate.grid(row=0, column=1, padx=5, pady=5, sticky=tk.N + tk.E + tk.S + tk.W)
        self.left_frame.grid_columnconfigure(1, weight=1)


root = tk.Tk()
mywin = MyWindow(root)
root.mainloop()

【讨论】:

  • 请记住,有时需要调用带有weight 参数的self.left_frame.rowconfigure()self.left_frame.columnconfigure(),以便sticky 可以工作。也许你应该在你的答案中包括这一点。
  • @Oli 您的建议绝对是正确的方向。但我仍然无法完美地填充框架内的框架。我在原始问题中编辑了该问题。您还有什么建议吗?
  • @codingsnake99 这些编辑好吗?
  • 非常感谢!它工作得很好,你提供的链接也对我理解有很大帮助。
猜你喜欢
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多