Tkinter Grid Problem - Çerçeveler hizalı değil

Sep 25 2020

Tkinter ile çalışmaya yeni başladım ve hala nasıl çalıştığına alışmaya çalışıyorum. 4 bölümlü bir çeşit ızgara menüsü hazırlamaya çalışıyordum.

Üstte uygulamanın başlığının bulunduğu bir çerçeve, solda bir çerçeve, uygulamayı yapılandırmak için bazı düğmeler ve ardından geri kalanında 4 eşit boyutlu çerçeve var.

Buradaki ana sorunum sol çerçeve ile diğer dördü arasındaki boş sütun, bunu 4 kare o boşluğu dolduracak şekilde nasıl ayarlayabilirim?

Kodun altına bakın:

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

Yanıtlar

1 BryanOakley Sep 25 2020 at 22:27

Kodunuzu sadece birkaç küçük değişiklikle düzeltebilirken, daha akıllı bir düzen oluşturmak için birkaç dakikanızı ayırmak, uygulama büyüdükçe kodunuzu değiştirmeyi çok daha kolay hale getirecektir.

Kodunuzu nasıl yeniden düzenleyeceğim konusunda size bazı tavsiyeler vereceğim. Cevabın sonunda son bir çalışan örnek var. Bunun% 90'ı orijinal kodunuzdur, ancak kullanıcı arayüzünü oluşturmayı kolaylaştırmak için arada sırada birkaç ince ayar ile.

gridHer şey için kullanma

Birincisi, bunu tavsiye değil kullanmak gridher şey için. Izgaralar oluşturmak için iyidir, ancak bazen bir pencerenin tamamını düzenlemenin daha iyi yolları vardır. Kullanıcı arayüzünüzü mantıksal gruplara ayırın ve ardından bu gruplamaları kullanarak düzenleyin.

Kullanıcı arayüzünüzü bölümler halinde düzenleyerek, yalnızca tek bir bölümü değiştirmeyi çok daha kolay hale getirir. Her şey için kullandığınızda grid, küçük bir değişiklik yapmak, yalnızca tek bir yeni parçacığı barındırmak için satır ve sütun numaralarını ve her şey için satır ve sütun aralıklarını ayarlamanız gereken bir düzine kod satırını değiştirmenizi gerektirebilir.

Düzen kodunu birlikte grupla

Ben de size yapılan çağrılar grup önerilir gridve packbirlikte ziyade kod boyunca onları yağmurlama. Tüm ilgili değişiklikler yayılmak yerine birbirine yakın olduğu için düzeni görselleştirmeyi çok daha kolay hale getiriyor ve değişiklik yapmayı daha kolay hale getiriyor.

Kullanıcı arayüzünü mantıksal bölümlere ayırın

Açıkça üç farklı alanınız var: üstte bir başlık, solda bazı düğmeler ve sonra diğer her şey. Öyleyse, sadece bunu yaratarak başlayın. packbir alanın kenarları boyunca düzenlenmiş eşyalarınız olduğunda tartışmasız en iyi seçimdir.

Öyleyse, bu üç alan için çerçeveler oluşturarak başlayın. Daha sonra packaçıklamanıza göre bunları kenarlar boyunca hizalamak için kullanabilirsiniz .

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)

Bu kaplara diğer widget'ları yerleştirin

En üstte bir çerçeve oluşturmuş olsanız bile, etiketi ve tarihi kök pencereye koyuyordunuz. Bunları çerçevenin içine yerleştirmelisiniz. Düğme eklemeye geldiğinizde, sol çerçeveye gitmeleri gerekir. Ve son olarak, diğer dört pencere için üçüncü çerçeveye gitmeleri gerekiyor.

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

gridAslında bir ızgarada bulunan dört çerçeve için kullanın

Kullanırken grid, en az bir satır ve bir sütuna bir ağırlık vermeniz gerekir, böylece gridpencere büyüdükçe veya küçüldükçe fazladan boşlukla ne yapılacağını bilir. Sizin durumunuzda, dört hücrenin hepsinin eşit olmasını istiyorsunuz, bu nedenle hepsine eşit ağırlık vermelisiniz.

Artık her şeyi tek bir ızgaraya zorlamak yerine yalnızca bu dört pencere için ızgarayı kullandığınızdan, anlamlı olan satır ve sütun numaralarını kullanabilirsiniz (ör: yapay olarak büyük satırlar yerine 0 ve 1 satırları, 0 ve 1 numaralı sütunlar) sütunlar ve açıklıklar).

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

Tam kodunuz böyle görünüyor. Başlık alanındaki metnin konumunu ayarlamadım, ancak GUI'nin diğer alanlarını etkilemeden değiştirmek kolaydır.

Ayrıca, pencereyi manuel olarak yeniden boyutlandırabileceğinizi ve boş noktalar bırakmak yerine her şeyin uygun şekilde büyüdüğünü veya küçüldüğünü unutmayın.

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

Mike67 Sep 25 2020 at 22:16

Tarih alanı tek bir sütunda olduğundan bir sonraki sütunu sağa doğru iter.

Tarih bloğunuzu güncelleyin ve ekleyin 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 

Çıktı