Hi,
I tried everything, but I can’t center the form horizontally, do you have an idea please?
It is always center a left like you can see on picture.
Thanks in advance for your help.
This is a part of my code :
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
from PIL import Image, ImageTk
import sqlite3
import datetime
import time
# Fonction pour se connecter à la base de données SQLite
def connect_to_database():
try:
conn = sqlite3.connect('C:/Users/David/projet_python/dist/manipulations.db')
return conn
except sqlite3.Error as e:
messagebox.showerror("Erreur", f"Erreur lors de la connexion à la base de données: {e}")
raise
# Fonction pour récupérer les utilisateurs de la base de données
def get_users():
conn = connect_to_database()
if conn is not None:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
users = cursor.fetchall()
conn.close()
return users
else:
return []
# Fonction pour masquer tous les cadres sauf celui de la section "After finalizing the analysis"
def show_finalizing_section():
for widget in scrollable_frame.winfo_children():
widget.grid_remove()
finalizing_frame.grid(row=0, column=0, columnspan=2, padx=10, pady=10, sticky="ew")
button_frame.grid(row=1, column=0, columnspan=2, pady=20)
# Fonction pour revenir à l'application principale
def return_to_main(message_window):
message_window.destroy()
root.deiconify()
show_finalizing_section()
# Fonction pour soumettre le formulaire
def submit_form():
user_info = nom_entry.get()
if not user_info:
messagebox.showerror("Erreur", "Veuillez remplir le champ 'Firstname and surname of user'.")
return
root.iconify()
message_window = tk.Toplevel(root)
message_window.title("Appareil en cours d'utilisation")
message_window.config(bg='red')
message_window.protocol("WM_DELETE_WINDOW", lambda: None)
message_window.resizable(False, False)
message_window.attributes("-toolwindow", True)
screen_width = message_window.winfo_screenwidth()
screen_height = message_window.winfo_screenheight()
window_width = 400
window_height = 250 # Adjusted height to accommodate the additional labels
# Conversion approximative de 8 cm en pixels
offset = 304
x_position = screen_width - window_width
y_position = screen_height - window_height - offset
message_window.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
frame = tk.Frame(message_window, bg='white', bd=10)
frame.pack(fill='both', expand=True, padx=20, pady=20)
message = f"Appareil actuellement utilisé par\n{user_info}"
label = tk.Label(frame, text=message, font=('Helvetica', 16), bg='white', fg='black')
label.pack(expand=True)
# Afficher l'heure actuelle
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
time_label = tk.Label(frame, text=f"Submitted at: {current_time}", font=('Helvetica', 12), bg='white')
time_label.pack(pady=5)
# Initialiser le temps de départ pour le compteur
start_time = time.time()
# Fonction pour mettre à jour le compteur
def update_timer():
elapsed_time = time.time() - start_time
minutes, seconds = divmod(int(elapsed_time), 60)
timer_label.config(text=f"Elapsed time: {minutes:02}:{seconds:02}")
frame.after(1000, update_timer)
# Label pour afficher le temps écoulé
timer_label = tk.Label(frame, text="Elapsed time: 00:00", font=('Helvetica', 12), bg='white')
timer_label.pack(pady=5)
# Démarrer le compteur
update_timer()
close_button = tk.Button(frame, text="Manipulations terminées", command=lambda: return_to_main(message_window))
close_button.pack(pady=10)
root = tk.Tk()
root.title("Nom de la machine scientifique")
root.config(bg='#f0f0f0')
root.attributes('-fullscreen', True)
root.bind('<Escape>', lambda e: root.quit())
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
large_font = ('Helvetica', 12)
main_frame = ttk.Frame(root, padding="20")
main_frame.pack(fill="both", expand=True)
canvas = tk.Canvas(main_frame)
scrollbar_y = ttk.Scrollbar(main_frame, orient="vertical", command=canvas.yview)
scrollbar_x = ttk.Scrollbar(main_frame, orient="horizontal", command=canvas.xview)
scrollbar_y.pack(side="right", fill="y")
scrollbar_x.pack(side="bottom", fill="x")
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
canvas.pack(side="left", fill="both", expand=True)
# Fonction pour ajouter le défilement avec la molette de la souris
def _on_mouse_wheel(event):
canvas.yview_scroll(int(-1*(event.delta/120)), "units")
canvas.bind_all("<MouseWheel>", _on_mouse_wheel)
style = ttk.Style()
style.theme_use('clam')
style.configure('TLabel', font=('Helvetica', 12), background='#f0f0f0')
style.configure('TButton', font=('Helvetica', 12), padding=5)
style.configure('TEntry', font=('Helvetica', 12), padding=5)
style.configure('TCombobox', font=('Helvetica', 12))
style.configure('TLabelframe.Label', font=('Helvetica', 13, 'bold'), foreground='blue')
style.configure('TLabelframe', background='#f0f0f0')
style.configure('TFrame', background='#f0f0f0')
root.config(bg='#f0f0f0')
main_frame.config(style='TFrame')
# Ajouter un conteneur centré pour le formulaire
center_frame = ttk.Frame(scrollable_frame)
center_frame.grid(row=0, column=0, sticky="nsew")
scrollable_frame.columnconfigure(0, weight=1)
scrollable_frame.rowconfigure(0, weight=1)
center_frame.columnconfigure(0, weight=1)
center_frame.grid_columnconfigure(0, weight=1) # Centrer le contenu dans center_frame
# Charger et afficher l'image
image_path = "C:/Users/David/projet_python/images/logo.png"
image = Image.open(image_path)
image = image.resize((600, 150), Image.Resampling.LANCZOS) # Redimensionner l'image pour l'élargir
photo = ImageTk.PhotoImage(image)
image_label = tk.Label(center_frame, image=photo, bg='#f0f0f0')
image_label.image = photo # Pour éviter que l'image soit garbage collected
image_label.grid(row=0, column=0, columnspan=2, pady=10)
label = ttk.Label(center_frame, text="Please complete this form during your manipulations", font=('Helvetica', 16, 'bold'))
label.grid(row=1, column=0, columnspan=2, pady=(0, 10))
personal_info_frame = ttk.Labelframe(center_frame, text="Personal informations", padding="10")
personal_info_frame.grid(row=2, column=0, padx=10, pady=10, sticky="ew")
users = get_users()
user_names = [user[1] for user in users]
user_combobox = ttk.Combobox(personal_info_frame, values=user_names)
user_combobox.grid(row=0, column=1, padx=10, pady=5, sticky="ew")
nom_label = ttk.Label(personal_info_frame, text="Firstname and surname of user:")
nom_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
nom_entry = ttk.Entry(personal_info_frame)
nom_entry.grid(row=0, column=1, padx=10, pady=5, sticky="ew")
matricula_label = ttk.Label(personal_info_frame, text="Enrolment number:")
matricula_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
matricula_entry = ttk.Entry(personal_info_frame)
matricula_entry.grid(row=1, column=1, padx=10, pady=5, sticky="ew")
manip_name_label = ttk.Label(personal_info_frame, text="Name of the manipulation/analysis/test:")
manip_name_label.grid(row=2, column=0, padx=10, pady=5, sticky="w")
manip_name_entry = ttk.Entry(personal_info_frame)
manip_name_entry.grid(row=2, column=1, padx=10, pady=5, sticky="ew")
lc_test_frame = ttk.Labelframe(center_frame, text="LC Test", padding="10")
lc_test_frame.grid(row=3, column=0, padx=10, pady=10, sticky="ew")
lc_test_label = ttk.Label(lc_test_frame, text="Have you passed the LC use test?")
lc_test_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
lc_test_var = tk.StringVar(value="")
def on_lc_test_change():
if lc_test_var.get() == "Yes" and system_free_var.get() == "Yes":
use_frame.grid()
samples_frame.grid()
finalizing_frame.grid()
button_frame.grid()
error_label.grid_remove()
else:
use_frame.grid_remove()
samples_frame.grid_remove()
finalizing_frame.grid_remove()
button_frame.grid_remove()
error_label.grid()
lc_test_yes = ttk.Radiobutton(lc_test_frame, text="Yes", variable=lc_test_var, value="Yes", command=on_lc_test_change)
lc_test_yes.grid(row=0, column=1, padx=10, pady=5, sticky="w")
lc_test_no = ttk.Radiobutton(lc_test_frame, text="No", variable=lc_test_var, value="No", command=on_lc_test_change)
lc_test_no.grid(row=0, column=2, padx=10, pady=5, sticky="w")
system_free_frame = ttk.Labelframe(center_frame, text="System free of issue?", padding="10")
system_free_frame.grid(row=4, column=0, padx=10, pady=10, sticky="ew")
system_free_label = ttk.Label(system_free_frame, text="Have you checked that the system is usable and free of issue?")
system_free_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
system_free_var = tk.StringVar(value="")
def on_system_free_change():
if system_free_var.get() == "Yes" and lc_test_var.get() == "Yes":
use_frame.grid()
samples_frame.grid()
finalizing_frame.grid()
button_frame.grid()
error_label.grid_remove()
else:
use_frame.grid_remove()
samples_frame.grid_remove()
finalizing_frame.grid_remove()
button_frame.grid_remove()
error_label.grid()
system_free_yes = ttk.Radiobutton(system_free_frame, text="Yes", variable=system_free_var, value="Yes", command=on_system_free_change)
system_free_yes.grid(row=0, column=1, padx=10, pady=5, sticky="w")
system_free_no = ttk.Radiobutton(system_free_frame, text="No", variable=system_free_var, value="No", command=on_system_free_change)
system_free_no.grid(row=0, column=2, padx=10, pady=5, sticky="w")
system_qualified_frame = ttk.Labelframe(center_frame, text="System qualified?", padding="10")
system_qualified_frame.grid(row=5, column=0, padx=10, pady=10, sticky="ew")
system_qualified_label = ttk.Label(system_qualified_frame, text="Has the system been qualified within less than one year (six months)?")
system_qualified_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
system_qualified_var = tk.StringVar(value="")
def on_system_qualified_change():
if system_qualified_var.get() == "No":
remarks_label.grid()
remarks_entry.grid()
else:
remarks_label.grid_remove()
remarks_entry.grid_remove()
system_qualified_yes = ttk.Radiobutton(system_qualified_frame, text="Yes", variable=system_qualified_var, value="Yes", command=on_system_qualified_change)
system_qualified_yes.grid(row=0, column=1, padx=10, pady=5, sticky="w")
system_qualified_no = ttk.Radiobutton(system_qualified_frame, text="No", variable=system_qualified_var, value="No", command=on_system_qualified_change)
system_qualified_no.grid(row=0, column=2, padx=10, pady=5, sticky="w")
remarks_label = ttk.Label(system_qualified_frame, text="Remarks:")
remarks_entry = ttk.Entry(system_qualified_frame)
remarks_label.grid_remove()
remarks_entry.grid_remove()
error_label = ttk.Label(center_frame, text="YOU MUST PASS THE LC TEST AND ENSURE THE SYSTEM IS FREE OF ISSUE BEFORE CONTINUING", font=('Helvetica', 12, 'bold'), foreground="red")
error_label.grid(row=6, column=0, padx=10, pady=5)
error_label.grid_remove()
use_frame = ttk.Labelframe(center_frame, text="Describe your use of:", padding="10")
use_frame.grid(row=7, column=0, padx=10, pady=10, sticky="ew")
solvents_label = ttk.Label(use_frame, text="Solvents:")
solvents_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
solvents_entry = ttk.Entry(use_frame)
solvents_entry.grid(row=0, column=1, padx=10, pady=5, sticky="ew")
channels_label = ttk.Label(use_frame, text="Channels (A1, B1, A2, B2):")
channels_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
channels_entry = ttk.Entry(use_frame)
channels_entry.grid(row=1, column=1, padx=10, pady=5, sticky="ew")
entries = [(solvents_label, solvents_entry, channels_label, channels_entry)]
def add_entry():
row = len(entries) * 2 + 2
new_solvent_label = ttk.Label(use_frame, text="Solvents:")
new_solvent_label.grid(row=row, column=0, padx=10, pady=5, sticky="w")
new_solvent_entry = ttk.Entry(use_frame)
new_solvent_entry.grid(row=row, column=1, padx=10, pady=5, sticky="ew")
new_channels_label = ttk.Label(use_frame, text="Channels (A1, B1, A2, B2):")
new_channels_label.grid(row=row+1, column=0, padx=10, pady=5, sticky="w")
new_channels_entry = ttk.Entry(use_frame)
new_channels_entry.grid(row=row+1, column=1, padx=10, pady=5, sticky="ew")
entries.append((new_solvent_label, new_solvent_entry, new_channels_label, new_channels_entry))
if len(entries) > 1:
remove_button.grid()
update_column_position()
def remove_entry():
if len(entries) > 1:
labels_and_entries = entries.pop()
for widget in labels_and_entries:
widget.grid_forget()
if len(entries) == 1:
remove_button.grid_remove()
update_column_position()
def update_column_position():
row = len(entries) * 2 + 2
column_desc_label.grid(row=row, column=0, padx=10, pady=5, sticky="w")
column_desc_text.grid(row=row, column=1, padx=10, pady=5, sticky="ew")
guard_column_desc_label.grid(row=row+1, column=0, padx=10, pady=5, sticky="w")
guard_column_desc_text.grid(row=row+1, column=1, padx=10, pady=5, sticky="ew")
column_label.grid(row=row+2, column=0, padx=10, pady=5, sticky="w")
column_entry.grid(row=row+2, column=1, padx=10, pady=5, sticky="ew")
add_button = ttk.Button(use_frame, text="Add Solvent Entry", command=add_entry)
add_button.grid(row=0, column=2, padx=10, pady=5)
remove_button = ttk.Button(use_frame, text="Remove Last Solvent Entry", command=remove_entry)
remove_button.grid(row=1, column=2, padx=10, pady=5)
remove_button.grid_remove()
column_desc_label = ttk.Label(use_frame, text="Column description:")
column_desc_text = tk.Text(use_frame, height=3, width=40)
guard_column_desc_label = ttk.Label(use_frame, text="Guard column description:")
guard_column_desc_text = tk.Text(use_frame, height=3, width=40)
column_label = ttk.Label(use_frame, text="Column (+guard column) internal ID:")
column_entry = ttk.Entry(use_frame)
update_column_position()
samples_frame = ttk.Labelframe(center_frame, text="Type of samples", padding="10")
samples_frame.grid(row=8, column=0, columnspan=2, padx=10, pady=10, sticky="ew")
samples_label = ttk.Label(samples_frame, text="Type of samples:")
samples_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
samples_entry = ttk.Entry(samples_frame)
samples_entry.grid(row=0, column=1, padx=10, pady=5, sticky="ew")
finalizing_frame = ttk.Labelframe(center_frame, text="After finalizing the analysis", padding="10")
finalizing_frame.grid(row=9, column=0, columnspan=2, padx=10, pady=10, sticky="ew")
injections_label = ttk.Label(finalizing_frame, text="How many injections have you performed (including blank …) ?")
injections_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
injections_entry = ttk.Entry(finalizing_frame)
injections_entry.grid(row=1, column=1, padx=10, pady=5, sticky="ew")
finalizing_label = ttk.Label(finalizing_frame, text="How have you rinsed your column and the system ? :")
finalizing_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
finalizing_entry = ttk.Entry(finalizing_frame)
finalizing_entry.grid(row=0, column=1, padx=10, pady=5, sticky="ew")
issue_var = tk.StringVar(value="No")
def on_issue_change():
if issue_var.get() == "Yes":
problem_description_frame.grid()
resolution_description_frame.grid()
instrument_manager_label.grid()
else:
problem_description_frame.grid_remove()
resolution_description_frame.grid_remove()
instrument_manager_label.grid_remove()
issue_label = ttk.Label(finalizing_frame, text="Have you got any issue with the system:")
issue_label.grid(row=2, column=0, padx=10, pady=5, sticky="w")
issue_yes = ttk.Radiobutton(finalizing_frame, text="Yes", variable=issue_var, value="Yes", command=on_issue_change)
issue_yes.grid(row=2, column=1, sticky="w")
issue_no = ttk.Radiobutton(finalizing_frame, text="No", variable=issue_var, value="No", command=on_issue_change)
issue_no.grid(row=2, column=2, sticky="w")
problem_description_frame = ttk.Labelframe(finalizing_frame, text="If Yes, please describe fully the problem(s):", padding="10")
problem_description_frame.grid(row=3, column=0, columnspan=3, padx=10, pady=5, sticky="ew")
problem_description = tk.Text(problem_description_frame, height=3, width=50)
problem_description.pack(padx=5, pady=5)
resolution_description_frame = ttk.Labelframe(finalizing_frame, text="If Yes, could you resolve the problem and how have you resolved it ?", padding="10")
resolution_description_frame.grid(row=4, column=0, columnspan=3, padx=10, pady=5, sticky="ew")
resolution_description = tk.Text(resolution_description_frame, height=3, width=50)
resolution_description.pack(padx=5, pady=5)
instrument_manager_label = tk.Label(finalizing_frame, text="If you have not yet informed an instrument manager, please do it as soon as possible.", font=('Helvetica', 12, 'bold'), fg="red", bg="white")
instrument_manager_label.grid(row=5, column=0, columnspan=3, padx=10, pady=5, sticky="ew")
instrument_manager_label.grid_remove()
problem_description_frame.grid_remove()
resolution_description_frame.grid_remove()
additional_info_label = ttk.Label(finalizing_frame, text="Any other important information to record?")
additional_info_label.grid(row=6, column=0, padx=10, pady=5, sticky="w")
additional_info_text = tk.Text(finalizing_frame, height=4, width=50)
additional_info_text.grid(row=6, column=1, columnspan=2, padx=10, pady=5, sticky="ew")
button_frame = ttk.Frame(center_frame)
button_frame.grid(row=10, column=0, columnspan=2, pady=20)
quit_button = ttk.Button(button_frame, text="Quitter", command=root.quit)
quit_button.pack(side="left", padx=10)
submit_button = ttk.Button(button_frame, text="Soumettre", command=submit_form, style='TButton')
submit_button.pack(side="left", padx=10)
def save_responses():
nom = nom_entry.get()
matricula = matricula_entry.get()
manipulation = manip_name_entry.get()
now = datetime.datetime.now()
formatted_date_time = now.strftime("%Y-%m-%d %H:%M:%S")
with open("responses.txt", "a") as file:
file.write(f"Time of record: {formatted_date_time}\n")
file.write(f"Name: {nom}\n")
file.write(f"Matricula: {matricula}\n")
file.write(f"Name of the manipulation/analysis/test: {manipulation}\n")
file.write("\n")
# Donner le focus à nom_entry une fois que la fenêtre est complètement chargée
root.after(100, lambda: nom_entry.focus_set())
root.mainloop()
