Layout changes on a different screen resolution problem

Hi Devs!
Iam very new to coding and i have a problem with my UI layout changes on defrent screen sizes even when i change the resolution of my screen here is my code i hope some one can help me with this Problem thanks in advance

import customtkinter as ctk
from tkinter import filedialog, Menu
from PIL import Image, ImageTk
import pandas as pd
import os
COLUMN_WIDTH = 20

def read_excel_file(file_path):
    try:
        df = pd.read_excel(file_path, header=None)
        return df.dropna()
    except FileNotFoundError:
        print("File not found. Please provide a valid file path.")
        return None
    except Exception as e:
        print("An error occurred:", e)
        return None

def extract_number(lines):
    extracted_numbers = []
    for line in lines:
        parts = line.strip().split('-')
        if len(parts) >= 3:
            extracted_numbers.append(parts[2])
    return extracted_numbers

def find_unique_codes(excel_df, text_numbers):
    try:
        unique_excel = excel_df[~excel_df.iloc[:, 0].astype(str).isin(text_numbers)]
        return unique_excel
    except KeyError:
        print("Error: The Excel file does not contain a column named 'Code'.")
        return None

def format_table(data, column_width):
    formatted_lines = []

    column_start_positions = [0] * len(data[0])

    for row in data:
        for idx, item in enumerate(row):
            column_start_positions[idx] = max(column_start_positions[idx], len(str(item)) + 2)

    border_line = "+" + "+".join(["-" * (width + 2) for width in column_start_positions]) + "+"
    formatted_lines.append(border_line)

    for row in data:
        formatted_row = []
        for idx, item in enumerate(row):
            formatted_item = str(item).ljust(column_start_positions[idx] - 1)[:column_start_positions[idx] - 1]
            formatted_row.append(formatted_item + " " * (column_start_positions[idx] - len(formatted_item)))
        formatted_lines.append("| " + " | ".join(formatted_row) + " |")
        formatted_lines.append(border_line)

    return "\n".join(formatted_lines)

def center_text(text_widget, text):
    text_widget.delete('1.0', ctk.END)
    lines = text.split('\n')
    for line in lines:
        line = line.strip()
        spaces_to_add = (text_widget.winfo_width() // 10 - len(line)) // 2
        centered_line = ' ' * spaces_to_add + line
        text_widget.insert(ctk.END, centered_line + '\n')

def compare_files():
    excel_file_paths = excel_file_entry.get().strip().split(';')
    text_file_path = text_file_entry.get().strip()

    print(f"Comparing files. Excel files: {excel_file_paths}")
    print(f"Text file: {text_file_path}")

    if all(excel_file_paths) and text_file_path:
        excel_dfs = []
        for excel_file_path in excel_file_paths:
            excel_df = read_excel_file(excel_file_path)
            if excel_df is not None:
                excel_dfs.append(excel_df)

        if excel_dfs:
            combined_excel_df = pd.concat(excel_dfs, ignore_index=True)
            with open(text_file_path, 'r') as file:
                lines = [line.strip() for line in file]

                text_numbers = extract_number(lines)
                unique_excel = find_unique_codes(combined_excel_df, text_numbers)

                excel_result_text.delete('1.0', ctk.END)
                text_result_text.delete('1.0', ctk.END)

                if unique_excel is not None:
                    if len(excel_file_paths) > 1:
                        unique_excel_count_value = len(unique_excel) - 2
                    else:
                        unique_excel_count_value = len(unique_excel) - 1
                    unique_excel_count.set(f"Nombre de colis Ă  justifier: {max(unique_excel_count_value, 0)}")
                    unique_text_count.set(f"Nombre de colis dans le dépot à vérifier : {len(set(text_numbers) - set(combined_excel_df.iloc[:, 0].astype(str)))}")

                    if not unique_excel.empty:
                        formatted_table = format_table(unique_excel.values.tolist(), COLUMN_WIDTH)
                        center_text(excel_result_text, formatted_table)
                    else:
                        center_text(excel_result_text, "No unique rows found in Excel file.\n")

                    unique_text = set(text_numbers) - set(combined_excel_df.iloc[:, 0].astype(str))
                    if unique_text:
                        for code in unique_text:
                            text_result_text.insert(ctk.END, code + '\n')
                    else:
                        text_result_text.insert(ctk.END, "No unique codes found in Text file.\n")
                else:
                    center_text(excel_result_text, "Error occurred while finding unique codes in Excel file.\n")
        else:
            center_text(excel_result_text, "Error reading Excel file(s).\n")
            text_result_text.delete('1.0', ctk.END)
    else:
        if not all(excel_file_paths):
            center_text(excel_result_text, "No Arrivé selected.\n")
        if not text_file_path:
            text_result_text.delete('1.0', ctk.END)
            text_result_text.insert(ctk.END, "No DĂ©pot selected.\n")




def export_results():
    file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
    if file_path:
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write("Unique Excel File Rows:\n")
            file.write(excel_result_text.get("1.0", ctk.END))
            file.write("\nUnique Text File Codes:\n")
            file.write(text_result_text.get("1.0", ctk.END))
        print(f"Results exported to {file_path}")

def copy_text(widget):
    widget.event_generate('<Control-c>')

def bind_right_click(widget):
    menu = Menu(widget, tearoff=0)
    menu.add_command(label="Copy", command=lambda: copy_text(widget))
    widget.bind("<Button-3>", lambda event: menu.post(event.x_root, event.y_root))

def browse_excel_file():
    excel_file_entry.delete(0, ctk.END)
    file_paths = filedialog.askopenfilenames(filetypes=[("Excel files", "*.xlsx;*.xls")])
    if file_paths:
        excel_file_entry.insert(ctk.END, ";".join(file_paths))


def browse_text_file():
    text_file_entry.delete(0, ctk.END)
    file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
    text_file_entry.insert(ctk.END, file_path)

def main():
    global excel_file_entry, text_file_entry, excel_result_text, text_result_text, unique_excel_count, unique_text_count

    ctk.set_default_color_theme("dark-blue")

    root = ctk.CTk()
    root.title("test")
    current_path = os.path.dirname(os.path.realpath(__file__))
    current_path = os.path.dirname(os.path.realpath(__file__))
    bg_image = Image.open(current_path + "/test_images/bg_gradient.jpg")
    #bg_image = bg_image.resize((root.winfo_screenwidth(), root.winfo_screenheight()), Image.LANCZOS)
    bg_image = ImageTk.PhotoImage(bg_image)
    bg_label = ctk.CTkLabel(root, image=bg_image)
    bg_label.grid(row=0, column=0, sticky="nsew")
    bg_label.lower()
    root.state('zoomed')
    root.geometry("800x600")

    selection_frame = ctk.CTkFrame(root, width=300, corner_radius=20)
    selection_frame.grid(row=0, column=0, padx=100, pady=50, sticky="n")

    excel_file_label = ctk.CTkLabel(selection_frame, text="Arrivé:", font=("Arial", 18, "bold"))
    excel_file_label.grid(row=0, column=0, padx=(20, 10), pady=10)

    excel_file_entry = ctk.CTkEntry(selection_frame, width=300)
    excel_file_entry.grid(row=0, column=1, padx=(10, 20), pady=10)

    excel_file_button = ctk.CTkButton(selection_frame, text="Parcourir", font=("Arial", 16, "bold"), command=browse_excel_file)
    excel_file_button.grid(row=0, column=2, padx=(10, 20), pady=10)

    text_file_label = ctk.CTkLabel(selection_frame, text="DĂ©pot:", font=("Arial", 18, "bold"))
    text_file_label.grid(row=1, column=0, padx=(20, 10), pady=10)

    text_file_entry = ctk.CTkEntry(selection_frame, width=300)
    text_file_entry.grid(row=1, column=1, padx=(10, 20), pady=10)

    text_file_button = ctk.CTkButton(selection_frame, text="Parcourir", font=("Arial", 16, "bold"), command=browse_text_file)
    text_file_button.grid(row=1, column=2, padx=(10, 20), pady=10)

    compare_button = ctk.CTkButton(selection_frame, text="Comparer", font=("Arial", 16, "bold"), command=compare_files)
    compare_button.grid(row=2, column=1, pady=20)

    export_button = ctk.CTkButton(selection_frame, text="Exporter", font=("Arial", 16, "bold"), command=export_results)
    export_button.grid(row=2, column=2, padx=(10, 20), pady=10)

    result_frame = ctk.CTkFrame(root, corner_radius=20)
    result_frame.grid(row=0, column=0, padx=500, pady=30, sticky="ew")
    excel_result_label = ctk.CTkLabel(result_frame, text="Les colis non scannés ou avec erreur de scanning :", font=("Arial", 20, "bold"))
    excel_result_label.pack(anchor=ctk.CENTER)

    unique_excel_count = ctk.StringVar()
    unique_excel_count_label = ctk.CTkLabel(result_frame, textvariable=unique_excel_count, font=("Arial", 16, "bold"))
    unique_excel_count_label.pack(anchor=ctk.CENTER)

    excel_result_frame = ctk.CTkFrame(result_frame, corner_radius=5)
    excel_result_frame.pack(expand=True, fill=ctk.BOTH, padx=4, pady=4)

    excel_result_text = ctk.CTkTextbox(excel_result_frame, wrap=ctk.NONE, width=100, font=("Calibri", 16, "bold"))
    excel_result_text.pack(expand=True, fill=ctk.BOTH, padx=5, pady=5)
    bind_right_click(excel_result_text)

    text_result_label = ctk.CTkLabel(result_frame, text="Les colis non arrivés dans le système :", font=("Arial", 20, "bold"))
    text_result_label.pack(anchor=ctk.CENTER)

    unique_text_count = ctk.StringVar()
    unique_text_count_label = ctk.CTkLabel(result_frame, textvariable=unique_text_count, font=("Arial", 16, "bold"))
    unique_text_count_label.pack(anchor=ctk.CENTER)

    text_result_frame = ctk.CTkFrame(result_frame, corner_radius=5)
    text_result_frame.pack(expand=True, fill=ctk.BOTH, padx=5, pady=5)

    text_result_text = ctk.CTkTextbox(text_result_frame, wrap=ctk.NONE, width=10, font=("Calibri", 18, "bold"))
    text_result_text.pack(expand=True, fill=ctk.BOTH, padx=5, pady=5)
    bind_right_click(text_result_text)

    root.mainloop()

if __name__ == "__main__":
    main()

There is code missing from your example.

Where are the imports that are needed to make the code work?

Please post code that someone else can run to test.

Thank you for the reply Barry the full code has been added

Thank you for formatting your code, it helps a lot.

To better help you a short, self contained,correct example would be necessary, and a better problem description than “i have a problem with my UI layout changes”.

I have no experience with CustomTkinter, which you seem to be using, but it seems to be not much different from tkinter, so here it goes:

Your using the grid layout manager here, which will take care of arranging and sizing your child windows. At the same time you are passing a width in pixels, this combination will not go down well probably when using different resolutions.

1 Like

here is the problem that i have the widget doesn’t fit on the screen when viewing it on a smaller screen resolution

it should be like this on every screen resolution

Think about this carefully, because you may be fighting different situations.

First, as I said before, do not use hardcoded width or height values on your child windows. The only place you should be using values is when you define your top windows (the one that is on your Tk and the TopLevels). My guess is that you want to set them depending on the desktop size, which you can get from tkinter. winfo_screenwidth and winfo_screenheigth are methods on widget which return those:

>>> f1.winfo_screenwidth()
1600
>>> f1.winfo_screenheight()
1200

…,where f1 is a created widget.

Where you may have trouble is that not every screen has the same size ratios. Most are 16:9 nowadays, but there are also 16:10 screens and I am looking at an ancient 4:3 screen, not to mention 5:4 screens. To have a good sizing for all of these, will be difficult.

Good luck.

1 Like