为了账号安全,请及时绑定邮箱和手机立即绑定

Tkinter 网格问题 - 框架未对齐

Tkinter 网格问题 - 框架未对齐

森林海 2023-09-05 21:03:09
我刚刚开始使用 tkinter,并且仍在努力适应它的工作方式。我试图准备某种包含 4 个部分的网格菜单。顶部有一个框架,带有应用程序的标题,左侧有一个框架,带有一些用于配置应用程序的按钮,然后,其余的有 4 个大小相同的框架。我的主要问题是左框架和其他四个框架之间的空白列,我该如何调整它以便 4 个方块填充该空间?请看下面的代码:import datetimeimport tkinter as tkfrom time import strftimewindow = tk.Tk()window.geometry("1400x800")window.configure(bg="white")window.rowconfigure(20,weight=1)window.columnconfigure(35,weight=1)window.title("Hello World App")entry_var_server = tk.StringVar(window,"")entry_var_db = tk.StringVar(window,"")entry_var_driver = tk.StringVar(window,"")def window_widgets():    db_ini_frame_top = tk.Frame(master=window,bg="#57b956",height=120,width=1400,highlightbackground="black",highlightthickness=2)    db_ini_frame_top.grid(rowspan=3,columnspan=34,sticky="w")    db_ini_label_top = tk.Label(master=window,text="Hello World",bg="#57b956")    db_ini_label_top.configure(font=("Calibri",26))    db_ini_label_top.grid(row=1,column=18,sticky="n")    def cur_date(dic = {'01':'st','21':'st','31':'st',                    '02':'nd','22':'nd',                    '03':'rd','23':'rd'}):        x = strftime('%A,  %B %d')        return x + dic.get(x[-2:],'th')+strftime(" %G - %H:%M")    date = cur_date()    db_ini_date = tk.Label(master=window,text=date,bg="#57b956")    db_ini_date.configure(font=("Calibri",12))    db_ini_date.grid(row=0,column=0,sticky="w")    db_ini_frame_left = tk.Frame(master=window,bg="light grey",height=800,width=120,colormap="new",highlightbackground="black",highlightthickness=2)    db_ini_frame_left.grid(row=3,rowspan=16,columnspan=2,sticky="w")
查看完整描述

2 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

虽然我们只需进行几个小更改即可修复您的代码,但花几分钟创建更智能的布局将使随着应用程序的增长修改代码变得更加容易。


我将提供一些关于如何重新组织代码的建议。答案的最后是一个最终的工作示例。其中 90% 是您的原始代码,但在这里或那里进行了一些调整,以使创建 UI 变得更容易。


不要用于grid一切

首先,我建议您不要用于grid所有用途。它对于创建网格很有用,但有时有更好的方法来布局整个窗口。将您的 UI 划分为逻辑分组,然后使用这些分组来布局它们。


通过将 UI 组织成多个部分,可以更轻松地修改单个部分。当您用于grid所有内容时,进行一个小的更改可能需要您更改十几行代码,您必须在其中调整行数和列数以及所有内容的行和列跨度,以便容纳一个新的小部件。


将布局代码分组在一起

我还建议您将grid和的调用分组pack在一起,而不是将它们散布在整个代码中。我发现它使布局可视化变得更加容易,并且更容易进行更改,因为所有相关的更改都彼此靠近而不是分散开来。


将 UI 划分为逻辑部分

显然,您有三个不同的区域:顶部的标题,左侧的一些按钮,然后是其他所有区域。因此,从创建它开始吧。pack当您将物品沿空间两侧排列时,可以说是最佳选择。


因此,首先为这三个区域创建框架。然后,您可以pack根据您的描述将它们沿边缘对齐。


db_ini_frame_top = tk.Frame(master=window, ...)

db_ini_frame_left = tk.Frame(master=window, ...)

db_ini_main = tk.Frame(master=window, ...)


db_ini_frame_top.pack(side="top", fill="x")

db_ini_frame_left.pack(side="left", fill="y")

db_ini_main.pack(side="top", fill="both", expand=True)

将其他小部件放入这些容器中

尽管您在顶部创建了一个框架,但您还是将标签和日期放在了根窗口中。您应该将它们放置在框架内。当您开始添加按钮时,它们应该位于左侧框架中。最后,对于其他四个窗口,它们需要进入第三帧。


db_ini_label_top = tk.Label(master=db_ini_frame_top, ...)

db_ini_date = tk.Label(master=db_ini_frame_top, ...)


db_ini_frame_center_nw = tk.Frame(master=db_ini_main, ...)

db_ini_frame_center_sw = tk.Frame(master=db_ini_main, ...)

db_ini_frame_center_ne = tk.Frame(master=db_ini_main, ...)

db_ini_frame_center_se = tk.Frame(master=db_ini_main, ...)

用于grid实际位于网格中的四个框架

使用 时grid,经验法则是您应该至少为一行和一列赋予权重,以便知道grid随着窗口增大或缩小如何处理额外空间。在您的情况下,您希望所有四个单元格相等,因此您应该给它们所有相同的权重。


因为您现在仅对这四个窗口使用网格,而不是尝试将所有内容强制放入单个网格中,所以您可以使用有意义的行号和列号(即:行 0 和 1、列 0 和 1,而不是人为地设置大行)以及列和跨度)。


db_ini_frame_center_nw = tk.Frame(master=db_ini_main,height=350,width=640,bg="blue")

db_ini_frame_center_sw = tk.Frame(master=db_ini_main,height=450,width=640,bg="light blue")

db_ini_frame_center_ne = tk.Frame(master=db_ini_main,height=350,width=640,bg="light blue")

db_ini_frame_center_se = tk.Frame(master=db_ini_main,height=450,width=640,bg="blue")


db_ini_main.grid_rowconfigure((0,1), weight=1)

db_ini_main.grid_columnconfigure((0,1), weight=1)


db_ini_frame_center_nw.grid(row=0,column=0, sticky="nsew")

db_ini_frame_center_sw.grid(row=0,column=1, sticky="nsew")

db_ini_frame_center_ne.grid(row=1,column=0, sticky="nsew")

db_ini_frame_center_se.grid(row=1,column=1, sticky="nsew")

这就是您的完整代码的样子。我没有调整标题区域中文本的位置,但是很容易更改它,而不会影响 GUI 的其他区域。


另请注意,您可以手动调整窗口大小,所有内容都会适当增大或缩小,而不是留下空白点。


import datetime

import tkinter as tk

from time import strftime


window = tk.Tk()

window.geometry("1400x800")

window.configure(bg="white")

window.rowconfigure(20,weight=1)

window.columnconfigure(35,weight=1)

window.title("Hello World App")

entry_var_server = tk.StringVar(window,"")

entry_var_db = tk.StringVar(window,"")

entry_var_driver = tk.StringVar(window,"")



def window_widgets():

    db_ini_frame_top = tk.Frame(master=window,bg="#57b956",height=120,width=1400,highlightbackground="black",highlightthickness=2)

    db_ini_frame_left = tk.Frame(master=window,bg="light grey",height=800,width=120,colormap="new",highlightbackground="black",highlightthickness=2)

    db_ini_main = tk.Frame(master=window,bg="light grey",height=800,width=120,colormap="new",highlightbackground="black",highlightthickness=2)


    db_ini_frame_top.pack(side="top", fill="x")

    db_ini_frame_left.pack(side="left", fill="y")

    db_ini_main.pack(side="top", fill="both", expand=True)


    db_ini_label_top = tk.Label(master=db_ini_frame_top,text="Hello World",bg="#57b956")

    db_ini_label_top.configure(font=("Calibri",26))

    db_ini_label_top.grid(row=1,column=18,sticky="n")


    def cur_date(dic = {'01':'st','21':'st','31':'st',

                    '02':'nd','22':'nd',

                    '03':'rd','23':'rd'}):

        x = strftime('%A,  %B %d')

        return x + dic.get(x[-2:],'th')+strftime(" %G - %H:%M")


    date = cur_date()

    db_ini_date = tk.Label(master=db_ini_frame_top,text=date,bg="#57b956")

    db_ini_date.configure(font=("Calibri",12))

    db_ini_date.grid(row=0,column=0,sticky="w")


    db_ini_frame_center_nw = tk.Frame(master=db_ini_main,height=350,width=640,bg="blue")

    db_ini_frame_center_sw = tk.Frame(master=db_ini_main,height=450,width=640,bg="light blue")

    db_ini_frame_center_ne = tk.Frame(master=db_ini_main,height=350,width=640,bg="light blue")

    db_ini_frame_center_se = tk.Frame(master=db_ini_main,height=450,width=640,bg="blue")


    db_ini_main.grid_rowconfigure((0,1), weight=1)

    db_ini_main.grid_columnconfigure((0,1), weight=1)


    db_ini_frame_center_nw.grid(row=0,column=0, sticky="nsew")

    db_ini_frame_center_sw.grid(row=0,column=1, sticky="nsew")

    db_ini_frame_center_ne.grid(row=1,column=0, sticky="nsew")

    db_ini_frame_center_se.grid(row=1,column=1, sticky="nsew")



window_widgets()

window.tk.mainloop()

https://img1.sycdn.imooc.com//64f727490001cead09460677.jpg

查看完整回答
反对 回复 2023-09-05
?
SMILET

TA贡献1796条经验 获得超4个赞

日期字段位于单列中,因此它将下一列推到右侧。


更新您的日期块并添加columnspan=4


date = cur_date()

db_ini_date = tk.Label(master=window,text=date,bg="#57b956")

db_ini_date.configure(font=("Calibri",12))

db_ini_date.grid(row=0,column=0,columnspan=4,sticky="w")   # Allow 4 columns for date 

输出

https://img1.sycdn.imooc.com//64f7275c00016cc902850289.jpg

查看完整回答
反对 回复 2023-09-05
  • 2 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信