2
votes

Les boutons tkinter ne s'alignent pas

J'essaie actuellement de créer ma fenêtre en fonction de ma structure filaire. Cependant, lors de l'utilisation de la grille, mes boutons obtiennent un espace étrange entre eux malgré la distribution de lignes appropriée dans les cellules. Je suis curieux, que se passe-t-il ici? Comment aligner correctement ces boutons?

Wireframe:  entrez la description de l'image ici

Sortie réelle:  entrez la description de l'image ici Notez l'espace entre les boutons "Effacer" et "Calculer".

Voici mon code pour les boutons:

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

Voici le code pour le fenêtre entière:

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)


2 commentaires

grid est comme un tableau dans Excel - clear est en ligne avec une grande Entry donc sa cellule utilise également de nombreux espaces. Vous devrez peut-être utiliser la grille à l'intérieur de la grille ou à l'intérieur du pack. Vous pouvez créer une grille avec une ligne et deux colonnes, dans la première colonne créer une grille intérieure (ou pack) avec toutes les entrées et dans la deuxième colonne créer une grille interne (ou pack) avec des boutons.


Vous devez spécifier rowspan dans box.grid (...) .


4 Réponses :


2
votes

Je suggère de diviser votre image principale en plusieurs images. Si les widgets de l'interface graphique deviennent plus complexes, il sera difficile de faire une géométrie correcte.

J'ai divisé le cadre principal en 2 parties, une partie supérieure et une partie inférieure afin que vous n'ayez pas besoin de gérer les colonnes et les lignes, ce qui est difficile en interface graphique complexe.

J'ai ajouté pady et padx pour l'écart entre les widgets, vous pouvez le modifier pour la taille nécessaire.

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


1 commentaires

Si l'interface graphique devient encore plus complexe, vous devez la diviser davantage.



1
votes

Vous pouvez ajouter rowspan = 3 à la zone Listbox . Ainsi, la Listbox box prendra autant que les trois boutons (Calculer, Effacer, Quitter). Listbox prend le même espace que trois boutons

Code complet:

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

Mais si vous voulez rapprocher les boutons et le La zone de liste box prend plus d'espace que les boutons puis ajoute rowspan = 12

 Les boutons sont proches les uns des autres et la listbox en prend plus espace


0 commentaires

2
votes

sous une solution oo.

Notez que la listbox est insérée dans un Frame séparé des autres.

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

 entrez la description de l'image ici a >


0 commentaires

2
votes

Une deuxième version presque égale à votre photo ... J'ai déplacé les boutons

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

entrez la description de l'image ici


0 commentaires