Tkinter网格问题-框架未对齐 [英] Tkinter Grid Problem - Frames not aligned

查看:74
本文介绍了Tkinter网格问题-框架未对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用tkinter,但我仍在尝试适应它的工作方式.我试图准备一种带有4个部分的网格菜单.

顶部有一个带有应用程序标题的框架,左侧是带有一些用于配置应用程序的按钮的框架,然后是其余四个相同大小的框架.

我的主要问题是左框架和其他四个框架之间的空白列,我该如何调整它,以便4个正方形填充该空间?

请参见下面的代码:

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_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")

    db_ini_frame_center_nw = tk.Frame(master=window,height=350,width=640,bg="blue")
    db_ini_frame_center_nw.grid(row=3,column=3,columnspan=16,rowspan=12,sticky="nw")

    db_ini_frame_center_sw = tk.Frame(master=window,height=450,width=640,bg="light blue")
    db_ini_frame_center_sw.grid(row=12,column=3,columnspan=16,rowspan=12,sticky="sw")

    db_ini_frame_center_ne = tk.Frame(master=window,height=350,width=640,bg="light blue")
    db_ini_frame_center_ne.grid(row=3,column=19,columnspan=16,rowspan=12,sticky="ne")

    db_ini_frame_center_se = tk.Frame(master=window,height=450,width=640,bg="blue")
    db_ini_frame_center_se.grid(row=12,column=19,columnspan=16,rowspan=12,sticky="se")

window_widgets()
window.tk.mainloop()

解决方案

While we can fix your code with just a couple of small changes, taking a few minutes to create a smarter layout will make it much easier to modify your code as the application grows.

I'm going to offer some advice about how I would reorganize your code. At the end of the answer is a final working example. 90% of it is your original code, but with a few tweaks here and there to make creating the UI easier.

Don't use grid for everything

First, I recommend that you not use grid for everything. It's good for creating grids, but there are sometimes better ways to lay out an entire window. Divide your UI into logical groupings, and then lay them out using those groupings.

By organizing your UI into sections it makes it much easier to modify just a single section. When you use grid for everything, making one small change might require you to change a dozen lines of code where you have to adjust row and column numbers, and row and column spans for everything just to accommodate a single new widget.

Group layout code together

I also recommend that you group your calls to grid and pack together rather than sprinkling them throughout the code. I find it makes it much easier to visualize the layout, and easier to make changes since all related changes are close to each other rather than spread out.

Divide the UI into logical sections

You clearly have three distinct areas: a title across the top, some buttons on the left, and then everything else. So, start by creating just that. pack is arguably the best choice when you have things arranged along the sides of a space.

So, start out by creating frames for those three areas. You can then use pack to align them along the edges per your description.

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)

Place other widgets in these containers

Even though you created a frame at the top, you were putting the label and date in the root window. You should be placing them inside the frame. When you get around to adding buttons, they should go in the left frame. And finally, for the other four windows, they need to go in the third frame.

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, ...)

Use grid for the four frames that are actually in a grid

When using grid, a rule of thumb is that you should give at least one row and one column a weight so that grid knows what to do with extra space as the window grows or shrinks. In your case you want all four cells to be equal, so you should give them all an equal weight.

Because you now are using grid only for these four windows instead of trying to force everything into a single grid, you can use row and column numbers that make sense (ie: rows 0 and 1, columns 0 and 1, instead of artificially large rows and columns and spans).

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")


This is what your full code looks like. I didn't adjust the location of the text in the title area, but it's easy to change it without affecting the other areas of the GUI.

Also, notice that you can manually resize the window and everything grows or shrinks appropriately rather than leaving empty spots.

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()

这篇关于Tkinter网格问题-框架未对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆