【问题标题】:tkinter buttons not aligningtkinter 按钮未对齐
【发布时间】:2019-04-04 02:12:21
【问题描述】:

我目前正在尝试根据我的线框创建我的窗口。然而,在使用网格时,尽管单元格中有适当的行分布,但我的按钮在它们之间会出现奇怪的空间。我很好奇,这是怎么回事?如何正确对齐这些按钮?

线框:

实际输出: 注意“清除”和“计算”按钮之间的空间。

这是我的按钮代码:

clearButton = Button(window, text="Clear", width = 10)
clearButton.grid(row = 3, column = 3)
computeButton = Button(window, text="Compute", width=10)
computeButton.grid(row = 4, column = 3)
exitButton = Button(window, text="Exit", width = 10)
exitButton.grid(row = 5, column = 3)

下面是整个窗口的代码:

import tkinter
from tkinter import *

window = tkinter.Tk()

window.geometry('600x400')

yearLabel = Label(window, text="Year")
yearLabel.grid(row=0, column=0)

amountLabel = Label(window, text="Amount")
amountLabel.grid(row=1, column=0)

rateLabel = Label(window, text="Rate")
rateLabel.grid(row=2, column=0)

monthlyPaymentLabel = Label(window, text="Monthly Payment")
monthlyPaymentLabel.grid(row = 0, column = 3)

totalInterestLabel = Label(window, text="Total Interest Paid")
totalInterestLabel.grid(row = 1, column = 3)




yearText = StringVar()
yt = Entry(window, textvariable=yearText)
yt.grid(row=0, column=1)

amountText = StringVar()
at = Entry(window, textvariable=yearText)
at.grid(row=1, column=1)

rateText = StringVar()
rt = Entry(window, textvariable=rateText)
rt.grid(row=2, column=1)




box = Listbox(window, height = 10, width = 50)
box.grid(row = 3, column = 0, columnspan=3)

scroll = Scrollbar(window)

scroll.grid(row=2, column=2, rowspan = 6)

box.configure(yscrollcommand = scroll.set)
scroll.configure(command = box.yview)


clearButton = Button(window, text="Clear", width = 10)
clearButton.grid(row = 3, column = 3)
computeButton = Button(window, text="Compute", width=10)
computeButton.grid(row = 4, column = 3)
exitButton = Button(window, text="Exit", width = 10)
exitButton.grid(row = 5, column = 3)

window.mainloop()

【问题讨论】:

  • grid 就像 Excel 中的表格 - clearEntry 大排成一行,因此它的单元格也使用了很多空格。您可能必须在网格内或包内使用网格。您可以使用一行和两列创建网格,在第一列中使用所有条目创建内部网格(或包),在第二列中使用按钮创建内部网格(或包)。
  • 您需要在box.grid(...)中指定rowspan

标签: python user-interface tkinter


【解决方案1】:

我建议将您的主框架分成多个框架。 如果 gui 小部件变得更复杂,那么做适当的几何图形会很痛苦。

我将主框架分为顶部和底部两部分,因此您无需处理复杂 gui 难以处理的列跨度和行跨度。

我为小部件之间的间隙添加了 pady 和 padx,您可以将其更改为所需的大小。

import tkinter
from tkinter import *

window = tkinter.Tk()
window.geometry('600x400')

top_frame = Frame(window)
top_frame.grid(row=0, column=0, sticky=W)

yearLabel = Label(top_frame, text="Year")
yearLabel.grid(row=0, column=0, padx=30)

amountLabel = Label(top_frame, text="Amount")
amountLabel.grid(row=1, column=0)

rateLabel = Label(top_frame, text="Rate")
rateLabel.grid(row=2, column=0)

yearText = StringVar()
yt = Entry(top_frame, textvariable=yearText)
yt.grid(row=0, column=1, padx=30)

amountText = StringVar()
at = Entry(top_frame, textvariable=yearText)
at.grid(row=1, column=1)

rateText = StringVar()
rt = Entry(top_frame, textvariable=rateText)
rt.grid(row=2, column=1)

monthlyPaymentLabel = Label(top_frame, text="Monthly Payment")
monthlyPaymentLabel.grid(row = 0, column = 3, padx=30)

totalInterestLabel = Label(top_frame, text="Total Interest Paid")
totalInterestLabel.grid(row = 1, column = 3)


bottom_frame = Frame(window)
bottom_frame.grid(row=1, column=0 )

box = Listbox(bottom_frame, height = 10, width = 80)
box.grid(row=0, column=0)

scroll = Scrollbar(bottom_frame)

scroll.grid(row=0, column=1)

box.configure(yscrollcommand = scroll.set)
scroll.configure(command = box.yview)

b_right_frame = Frame(bottom_frame)
b_right_frame.grid(row=0, column=2, sticky=N)

clearButton = Button(b_right_frame, text="Compute", width = 10)
clearButton.grid(row = 0, column = 2, sticky=N)
computeButton = Button(b_right_frame, text="Clear", width=10)
computeButton.grid(row = 1, column = 2, sticky=N, pady=10)
exitButton = Button(b_right_frame, text="Exit", width = 10)
exitButton.grid(row = 2, column = 2, sticky=N)

window.mainloop()

【讨论】:

  • 如果 gui 变得更加复杂,那么你应该进一步划分它。
【解决方案2】:

第二个版本几乎等于你的图片...我已经移动了按钮

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

class App(tk.Frame):

    def __init__(self,):

        super().__init__()

        self.master.title("Hello World")
        self.year = tk.IntVar()
        self.amount = tk.DoubleVar()
        self.rate = tk.DoubleVar()
        self.interest = tk.DoubleVar()
        self.payment = tk.DoubleVar()

        self.init_ui()


    def init_ui(self):

        w = tk.Frame()

        r =0
        ttk.Label(w, text="Year:").grid(row=r, sticky=tk.W)
        ttk.Entry(w,width=8, textvariable=self.year).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)

        r =1
        ttk.Label(w, text="Amount:").grid(row=r, sticky=tk.W)
        ttk.Entry(w,width=8, textvariable=self.amount).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)

        r =2
        ttk.Label(w, text="Rate:").grid(row=r, sticky=tk.W)
        ttk.Entry(w,width=8, textvariable=self.rate).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)

        r =0
        ttk.Label(w, text="Monthly Payment:").grid(row=r, column=3, sticky=tk.W)
        ttk.Entry(w,width=8, textvariable=self.payment).grid(row=r, column=4, padx=5, pady=5,sticky=tk.W)

        r =1
        ttk.Label(w, text="Total Interest Paid:").grid(row=r, column=3, sticky=tk.W)
        ttk.Entry(w,width=8, textvariable=self.interest).grid(row=r, column=4, padx=5, pady=5,sticky=tk.W)

        w.grid(row=0, column=0, sticky=tk.N+tk.W+tk.S+tk.E)

        #lisbox
        w2 = tk.Frame()

        self.get_listbox(w2,0,0,10,45).grid(padx=5, pady=5)

        w2.grid(row=3, column=0, sticky=tk.N+tk.W+tk.S+tk.E)

        #buttons
        bts = [('Clear', self.on_clear),
               ('Compute', self.on_compute),
               ('Exit', self.on_exit),]

        w3 = tk.Frame()

        for r, btn in enumerate(bts):
            b = ttk.Button(w3, text=btn[0], underline=0)
            b.bind("<Button-1>", btn[1])
            b.grid(row=r, column=0, sticky=tk.N, padx=5, pady=5)

        w3.grid(row=3,column =4, sticky=tk.N)


    def on_clear(self,evt=None):
        msg = "To assign!"
        messagebox.showwarning(self.master.title(),msg)      

    def on_compute(self,evt=None):
        msg = "To assign!"
        messagebox.showwarning(self.master.title(),msg)      

    def on_exit(self,evt=None):
        self.master.destroy()

    def get_listbox(self, container, row, col, height=None, width=None):

        sb = tk.Scrollbar(container,orient=tk.VERTICAL)

        w = tk.Listbox(container,
                    relief=tk.GROOVE,
                    selectmode=tk.BROWSE,
                    height=height,
                    width=width,
                    background = 'white',
                    font='TkFixedFont',
                    yscrollcommand=sb.set,)

        sb.config(command=w.yview)

        sb.grid(column=1, sticky=tk.N+tk.S)
        w.grid(row=row, column=col)

        return w        

if __name__ == '__main__':
    app = App()
    app.mainloop()

【讨论】:

    【解决方案3】:

    低于 oo 解决方案。

    请注意,列表框插入到与其他框架分开的框架中。

    import tkinter as tk
    from tkinter import ttk
    from tkinter import messagebox
    
    class App(tk.Frame):
    
        def __init__(self,):
    
            super().__init__()
    
            self.master.title("Hello World")
    
            self.year = tk.IntVar()
            self.amount = tk.DoubleVar()
            self.rate = tk.DoubleVar()
            self.interest = tk.DoubleVar()
            self.payment = tk.DoubleVar()
    
            self.init_ui()
    
        def init_ui(self):
    
            w = tk.Frame()
    
            r =0
            ttk.Label(w, text="Year:").grid(row=r, sticky=tk.W)
            ttk.Entry(w,width=8, textvariable=self.year).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)
    
            r =1
            ttk.Label(w, text="Amount:").grid(row=r, sticky=tk.W)
            ttk.Entry(w,width=8, textvariable=self.amount).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)
    
            r =2
            ttk.Label(w, text="Rate:").grid(row=r, sticky=tk.W)
            ttk.Entry(w,width=8, textvariable=self.rate).grid(row=r, column=1, padx=5, pady=5,sticky=tk.W)
    
            r =0
            ttk.Label(w, text="Monthly Payment:").grid(row=r, column=3, sticky=tk.W)
            ttk.Entry(w,width=8, textvariable=self.payment).grid(row=r, column=4, padx=5, pady=5,sticky=tk.W)
    
            r =1
            ttk.Label(w, text="Total Interest Paid:").grid(row=r, column=3, sticky=tk.W)
            ttk.Entry(w,width=8, textvariable=self.interest).grid(row=r, column=4, padx=5, pady=5,sticky=tk.W)
    
            c =5
            bts = [('Clear', self.on_clear),
                   ('Compute', self.on_compute),
                   ('Exit', self.on_exit),]
    
            for r, btn in enumerate(bts):
                b = ttk.Button(w, text=btn[0], underline=0)
                b.bind("<Button-1>", btn[1])
                b.grid(row=r, column=c, sticky=tk.W+tk.E, padx=5, pady=5)
    
            w.grid(row=0, column=0, sticky=tk.N+tk.W+tk.S+tk.E)
    
            w2 = tk.Frame()
    
            self.get_listbox(w2,0,0,10,45).grid(padx=5, pady=5)
    
            w2.grid(sticky=tk.W)
    
        def on_clear(self,evt=None):
            msg = "To assign!"
            messagebox.showwarning(self.master.title(),msg)      
    
        def on_compute(self,evt=None):
            msg = "To assign!"
            messagebox.showwarning(self.master.title(),msg)      
    
        def on_exit(self,evt=None):
            self.master.destroy()
    
        def get_listbox(self, container, row, col, height=None, width=None):
    
            sb = tk.Scrollbar(container,orient=tk.VERTICAL)
    
            w = tk.Listbox(container,
                        relief=tk.GROOVE,
                        selectmode=tk.BROWSE,
                        height=height,
                        width=width,
                        background = 'white',
                        font='TkFixedFont',
                        yscrollcommand=sb.set,)
    
            sb.config(command=w.yview)
    
            sb.grid(column=1, sticky=tk.N+tk.S)
            w.grid(row=row, column=col)
    
            return w        
    
    if __name__ == '__main__':
        app = App()
        app.mainloop()
    

    【讨论】:

      【解决方案4】:

      您可以将rowspan = 3 添加到Listbox box。所以Listboxbox 将占用三个按钮(计算、清除、退出)占用的空间。

      完整代码:

      import tkinter
      from tkinter import *
      
      window = tkinter.Tk()
      window.geometry('600x400')
      
      yearLabel = Label(window, text="Year")
      yearLabel.grid(row=0, column=0)
      
      amountLabel = Label(window, text="Amount")
      amountLabel.grid(row=1, column=0)
      
      rateLabel = Label(window, text="Rate")
      rateLabel.grid(row=2, column=0)
      
      monthlyPaymentLabel = Label(window, text="Monthly Payment")
      monthlyPaymentLabel.grid(row=0, column=3)
      
      totalInterestLabel = Label(window, text="Total Interest Paid")
      totalInterestLabel.grid(row=1, column=3)
      
      yearText = StringVar()
      yt = Entry(window, textvariable=yearText)
      yt.grid(row=0, column=1)
      
      amountText = StringVar()
      at = Entry(window, textvariable=yearText)
      at.grid(row=1, column=1)
      
      rateText = StringVar()
      rt = Entry(window, textvariable=rateText)
      rt.grid(row=2, column=1)
      
      box = Listbox(window, height=10, width=50)
      box.grid(row=3, column=0, rowspan=3, columnspan=3)
      
      scroll = Scrollbar(window)
      scroll.grid(row=2, column=2, rowspan=6)
      
      box.configure(yscrollcommand=scroll.set)
      scroll.configure(command=box.yview)
      
      
      clearButton = Button(window, text="Clear", width=10)
      clearButton.grid(row=3, column=3)
      
      computeButton = Button(window, text="Compute", width=10)
      computeButton.grid(row=4, column=3)
      
      exitButton = Button(window, text="Exit", width=10)
      exitButton.grid(row=5, column=3)
      
      window.mainloop()
      

      但是,如果您想让按钮更靠近并且 Listbox box 比按钮占用更多空间,请添加 rowspan = 12

      【讨论】:

        猜你喜欢
        • 2021-01-20
        • 1970-01-01
        • 2020-03-11
        • 2014-04-28
        • 1970-01-01
        • 2022-01-05
        • 2016-08-28
        • 1970-01-01
        • 2019-05-31
        相关资源
        最近更新 更多