Search code examples
pythontkintertkinter-buttoncustomtkinter

Positioning of Tkinter Elements


I have a simple problem, but I'm not able to solve it. I've a tkinter GUI with 4 respectively 5 Buttons. There is a button in the middle, which choose an image. After the user chose the image the GUI will show so values below the "choose button". Then should their be two respectively three buttons on the left side and one Button on the right side.

My problem is the positioning of the two/three buttons on the right side. they are next to each other instead of under each other.

This is my code:

import tensorflow.keras.layers as tfl
import keras
import tkinter as tk
import tkinter.messagebox as messagebox
from tkinter import filedialog
from PIL import ImageTk, Image
import numpy as np
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.applications.vgg19 import preprocess_input
from tensorflow.keras.models import load_model
from shutil import copy2
import os


# Laden des Modells
model = load_model(r'model.h5')
# 230524xception_erweitert_4096_2048_drop_05_32er_Augmen_batch.h5
# VGG19_4096_4096_Erweiterung1_2_batch_8_Augmentation.h5

# Definieren der GUI
root = tk.Tk()
root.title("Binäre Klassifizierung")

# Definition der Fenstergroesse
canvas = tk.Canvas(root, width=506, height=500)
canvas.pack()

# Funktion zur Auswahl des Bildes und Vorverarbeitung
def predict():
    # Dateiauswahl vorgewählter Ordner
    initial_dir_open = ''#r"\\S-KSE-12\Daten\Trosifol\ALLE\TROSIFOL\Frick\Black Belt Projekt\MSA Planlagenbeurteilung"
    
    # Dialog zum Laden der Datei
    file_path = filedialog.askopenfilename(initialdir=initial_dir_open)
    
    # Speichern des ausgewählten Bildpfads in einer globalen Variable
    global selected_image
    
    selected_image = file_path
    
    # Laden des Bildes und Anpassen der Größe
    image_original = Image.open(file_path).convert("RGB")
    image = Image.open(file_path)
    image = image.resize((224, 224))
    
    # Vorverarbeitung des Bildes
    image_array = img_to_array(image)
    image_array = np.expand_dims(image_array, axis=0)
    image_array = preprocess_input(image_array)
    
    # Vorhersage des Modells
    predictions = model.predict(image_array)
    score = predictions[0][0]
    if score > 0.5:
        label = "n.i.o."
        color = "red"
    else:
        label = "i.o."
        color = "green"
    
    # Ausgabe des Dateinamens
    filename = os.path.splitext(os.path.basename(file_path))[0]
    lbl_filename.config(text="" + filename, fg = color, font=("Arial",  20, "bold"))
    
    # Ausgabe der Vorhersage
    prediction_label.config(text=label, fg=color, font=("Arial",  20, "bold"))
    score_label.config(text="Score: {:.2f}".format(score))
    
    # Ausgabe des Bildes
    img = Image.open(file_path).resize((500, 500))
    img = ImageTk.PhotoImage(img)
    canvas.create_image(0, 0, anchor=tk.NW, image=img)
    canvas.image = img



# Globale Variable für den Speicherpfad
save_path = r""

# Funktion zum Speichern des Bildes in einem vorgegebenen Ordner
def save_wrong_classification():
    global selected_image
    if selected_image:
        # Ausschneiden des reinen Dateinamens
        old_filename = os.path.basename(selected_image)
        # Startornder
        initial_dir_save = r""
        # Öffnen des Dialogfensters zum Speichern des Bildes an einem benutzerdefinierten Speicherort
        save_path = filedialog.asksaveasfilename(defaultextension=".jpg",
                                                 initialfile=old_filename,
                                                 initialdir=initial_dir_save)
        if save_path:
            # Kopieren des ausgewählten Bildes an den benutzerdefinierten Speicherort
            copy2(selected_image, save_path)
            messagebox.showinfo("Speichern erfolgreich", "Das Bild wurde erfolgreich gespeichert.")
        else:
            messagebox.showwarning("Kein Speicherpfad ausgewählt", "Es wurde kein Speicherpfad ausgewählt.")
    else:
        messagebox.showwarning("Kein Bild ausgewählt", "Es wurde kein Bild ausgewählt.")
        
# Funktion zum Speichern der richtig klassifizierten Bilder
def save_right_io_classification():
    global selected_image
    if selected_image:
        # Ausschneiden des reinen Dateinamens
        old_filename = os.path.basename(selected_image)
        # Startornder. Leer weil 
        initial_dir_save = r""
        # Öffnen des Dialogfensters zum Speichern des Bildes an einem benutzerdefinierten Speicherort
        save_path = filedialog.asksaveasfilename(defaultextension=".jpg",
                                                 initialfile=old_filename,
                                                 initialdir=initial_dir_save)
        if save_path:
            # Kopieren des ausgewählten Bildes an den benutzerdefinierten Speicherort
            copy2(selected_image, save_path)
            messagebox.showinfo("Speichern erfolgreich", "Das Bild wurde erfolgreich gespeichert.")
        else:
            messagebox.showwarning("Kein Speicherpfad ausgewählt", "Es wurde kein Speicherpfad ausgewählt.")
    else:
        messagebox.showwarning("Kein Bild ausgewählt", "Es wurde kein Bild ausgewählt.")
        
def save_right_nio_classification():
    global selected_image
    if selected_image:
        # Ausschneiden des reinen Dateinamens
        old_filename = os.path.basename(selected_image)
        # Startornder. Leer weil 
        initial_dir_save = r""
        # Öffnen des Dialogfensters zum Speichern des Bildes an einem benutzerdefinierten Speicherort
        save_path = filedialog.asksaveasfilename(defaultextension=".jpg",
                                                 initialfile=old_filename,
                                                 initialdir=initial_dir_save)
        if save_path:
            # Kopieren des ausgewählten Bildes an den benutzerdefinierten Speicherort
            copy2(selected_image, save_path)
            messagebox.showinfo("Speichern erfolgreich", "Das Bild wurde erfolgreich gespeichert.")
        else:
            messagebox.showwarning("Kein Speicherpfad ausgewählt", "Es wurde kein Speicherpfad ausgewählt.")
    else:
        messagebox.showwarning("Kein Bild ausgewählt", "Es wurde kein Bild ausgewählt.")

def input_path():
    global Eingabepfad
    Eingabepfad = Entry(root)
        
        
# GUI-Elemente

# Auswahl Button
select_button = tk.Button(root, text="Bild auswählen", command=predict)
select_button.pack(side = "bottom", pady=20)

# Button fuer die Fehlklassifizierungen
save_button = tk.Button(root, text="Falsch klassifiziert", command=save_wrong_classification)
save_button.pack(side = "right", pady=20)

# Button fuer die Fehlklassifizierungen
save_button_io = tk.Button(root, text="Richtig klassifiziert i. O.", command=save_right_io_classification)
save_button_io.pack(padx = 1, pady = 5, fill = 'y')

# Button fuer die Fehlklassifizierungen
save_button_nio = tk.Button(root, text="Richtig klassifiziert n. i. O.", command=save_right_nio_classification)
save_button_nio.pack(padx = 1, pady = 5, fill = 'y')

# Ausgabe des Dateinamens
lbl_filename = tk.Label(root, text="", font=("Arial bold",  25))
lbl_filename.pack()

# Ausgabe der Vorhersage
prediction_label = tk.Label(root, text="", font=("Helvetica", 24))
prediction_label.pack(side = "bottom")

# Ausgabe des Decisionscores
score_label = tk.Label(root, text="", font=("Helvetica", 18))
score_label.pack(side = "bottom")

# Ende der Hauptschleife für die GUI
root.mainloop()

Does anyone have an idea how I can make the buttons "save_button_io" and "save_button_nio" can be positioned below each other?

I tried to use the pack-manager and the grid-manager for positioning, but it doesn't work as well as i've imagined

I want an GUI, which look like this. 1 Actually it looks like this. 2


Solution

  • You posted way too much code to try to edit on our part, but here is a simple script using grid. enter image description here

    import tkinter as tk
    
    root = tk.Tk()
    canvas = tk.Canvas(root,width=506,height=500)
    canvas.grid(row=0,column=0,columnspan=3)
    
    button1 = tk.Button(root,text='Button1',font=('Arial',14))
    button1.grid(row=1,column=0)
    
    button2 = tk.Button(root,text='Button2',font=('Arial',14))
    button2.grid(row=2,column=0)
    
    button3 = tk.Button(root,text='Button3',font=('Arial',14))
    button3.grid(row=3,column=0)
    
    button4 = tk.Button(root,text='Button4',font=('Arial',14))
    button4.grid(row=1,column=2)
    
    choose = tk.Button(root,text='Choose',font=('Arial',14))
    choose.grid(row=1,column=1)
    
    root.mainloop()