Bonjour, j’ai écris le code d’un bloc note avec une calculatrice intégrée grace à une option de liste déroulante, sauf que quand je clique dessus la calculatrice s’affiche bien mais aucun de ses boutons ne marche et j’ai les erreurs
Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\tkinter__init.py", line 1948, in call__ return self.func(*args) ^^^^^^^^^^^^^^ File "C:\Users\HP\Downloads\projet_GUI-nadia\noteit.py", line 105, in sign_change if calc_operator[0] == '-’:
~~~~~~~~~~~~~^^^
IndexError: string index out of range Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\tkinter__init.py", line 1948, in call return self.func(*args) ^^^^^^^^^^^^^^ File "C:\Users\HP\Downloads\projet_GUI-nadia\noteit.py", line 376, in calculatrice Calculatrice.mainloop() File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\tkinter__init.py", line 1485, in mainloop self.tk.mainloop(n) KeyboardInterrupt
Voici mon code
# iportation des differentes biblioteques
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from tkinter import font
from tkinter import colorchooser
from tkinter import simpledialog
from tkinter import *
import math
calc_operator = ""
# Fonction qui va contenir la calculatrice
def calculatrice():
# Création de la fenetre
Calculatrice = Tk()
Calculatrice.configure(bg="#293C4A", bd=10)
Calculatrice.title("Ma Calculatrice")
# crétion d'une variable qui va contenir le texte entré qu'on va manipuler tout au long du code
global calc_operator
# définition d'une instance qui va permettre d'afficher les entrées
text_input = StringVar()
# Différentes fonctions du back end de la calculatrice
# Fonction qui va permettre d'entrer le texte
def button_write(char):
# globale pour pouvoir l'utiliser librement dans la fonction et partout dans le code
calc_operator = ""
# renvoyer le nombre sous forme d'une chaine de caractère
calc_operator += str(char)
# affcicher le nombre entrer
text_input.set(calc_operator)
# Fonction qui efface tout le contenu de la calculatrice
def button_clear_all():
global calc_operator
# vider le contenu de la variable
calc_operator = ""
# afficher le vide
text_input.set("")
# Fonction pour effacer un à un les éléments entrés
def button_delete():
global calc_operator
# variable qui va recevoir ce qui était précédemment à l'écrn moin un caractère
text = calc_operator[:-1]
calc_operator = text
text_input.set(text)
# Fonction qui calcule le factoriel d'un nombre
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
# Fonction qui va afficher le factoriel précédemment calculé
def fact_func():
global calc_operator
# on convertit les caractères entrés en nombre, on calcule le factoriel et on le renvoie sous forme de chaine de caractère
result = str(factorial(int(calc_operator)))
calc_operator = result
text_input.set(result)
# Fonction qui calcule le sinus d'un angle
def sinus():
global calc_operator
# on convertit les caractères entrés en nombre, on calcule son sinus (déjà défini dans math.radian) et on le renvoie sous forme de chaine de caractère
result = str(math.sin(math.radians(int(calc_operator))))
calc_operator = result
text_input.set(result)
# Fonction qui calcule le cosinus d'un angle
def cosinus():
global calc_operator
# on convertit les caractères entrés en nombre, on calcule son cosinus (déjà défini dans math.radian) et on le renvoie sous forme de chaine de caractère
result = str(math.cos(math.radians(int(calc_operator))))
calc_operator = result
text_input.set(result)
# Fonction qui calcule la tangente d'un angle
def tangente():
global calc_operator
# on convertit les caractères entrés en nombre, on calcule sa tangente (déjà défini dans math.radian) et on le renvoie sous forme de chaine de caractère
result = str(math.tan(math.radians(int(calc_operator))))
calc_operator = result
text_input.set(result)
# Fontion qui calcule le carré d'un nombre et renvoie une erreur si le nombre entré est négatif
def square_root():
global calc_operator
if int(calc_operator) >= 0:
temp = str(eval(calc_operator + '**(1/2)'))
calc_operator = temp
else:
temp = "ERROR"
text_input.set(temp)
# Fonction qui change le signe du nombre entré
def sign_change():
global calc_operator
# si le premier caractère est entré est - alors on le retire et on stocke le tout dans une variable, sinon on ajoute le - devant
if calc_operator[0] == '-':
new_number = calc_operator[1:]
else:
new_number = '-' + calc_operator
calc_operator = new_number
text_input.set(new_number)
# Fonction qui transforme un nombre en pourcentage
def percent():
global calc_operator
new_number = str(eval(calc_operator + '/100'))
calc_operator = new_number
text_input.set(new_number)
# Fonction qui affiche le résultat(bouton égal=)
def button_equal():
global calc_operator
result = str(eval(calc_operator))
text_input.set(result)
calc_operator = result
# Variables à utiliser dans les calculs
sin, cos, tan = math.sin, math.cos, math.tan
p = math.pi
E = '*10**'
# Création de l'espace pour entrer le texte et la grille dans laquelle les boutons seront classés
text_display = Entry(Calculatrice,
font=('sans-serif',
20, 'bold'),
textvariable=text_input,
bd=5, insertwidth=5,
bg='#BBB', justify='right').grid(columnspan=5,
padx=10,
pady=15)
# paramètres par défaut des boutons des fonctions
button_params = {'bd': 5,
'fg': '#BBB',
'bg': '#3C3636',
'font': ('sans-serif',
20,
'bold')}
# paramètres par défaut pour les autres boutons
button_params_main = {'bd': 5,
'fg': '#000',
'bg': '#BBB',
'font': ('sans-serif',
20,
'bold')}
# Première ligne
# bouton pour le sinus d'un angle en dégré
sine = Button(Calculatrice,
button_params,
text='sin',
command=sinus).grid(row=1,
column=0,
sticky="nsew")
# bouton pour le osinus d'un angle en dégré
cosine = Button(Calculatrice,
button_params,
text='cos',
command=cosinus).grid(row=1,
column=1,
sticky="nsew")
# bouton pour la tangente
tangent = Button(Calculatrice,
button_params,
text='tan',
command=tangente).grid(row=1,
column=2,
sticky="nsew")
# Carré d'un nombre
carre_num = Button(Calculatrice,
button_params,
text='x\u00B2',
command=lambda: button_write('**2')).grid(row=1,
column=3,
sticky="nsew")
# Nombre Pi(3.14...)
pi_num = Button(Calculatrice,
button_params,
text='π',
command=lambda: button_write(str(math.pi))).grid(row=1,
column=4,
sticky="nsew")
# Deuxième ligne
# Racine carrée
square_root = Button(Calculatrice,
button_params,
text='\u00B2\u221A',
command=square_root).grid(row=2,
column=0,
sticky="nsew")
# Parenthèse gauche
left_par = Button(Calculatrice,
button_params, text='(',
command=lambda: button_write('(')).grid(row=2,
column=1,
sticky="nsew")
# Parenthèse droite
right_par = Button(Calculatrice,
button_params,
text=')',
command=lambda: button_write(')')).grid(row=2,
column=2,
sticky="nsew")
# Changer le signe d'un objet
signs = Button(Calculatrice,
button_params,
text='\u00B1',
command=sign_change).grid(row=2,
column=3,
sticky="nsew")
# Bouton pourcentage
percentage = Button(Calculatrice,
button_params, text='%',
command=percent).grid(row=2,
column=4,
sticky="nsew")
# Troisième ligne
# Chiffre 7
button_7 = Button(Calculatrice,
button_params_main,
text='7',
command=lambda: button_write('7')).grid(row=3,
column=0,
sticky="nsew")
# Chiffre 8
button_8 = Button(Calculatrice,
button_params_main,
text='8',
command=lambda: button_write('8')).grid(row=3,
column=1,
sticky="nsew")
# Chiffre 9
button_9 = Button(Calculatrice,
button_params_main,
text='9',
command=lambda: button_write('9')).grid(row=3,
column=2,
sticky="nsew")
# Supprimer un caractère
delete_one = Button(Calculatrice,
bd=5,
fg='#000',
font=('sans-serif',
20,
'bold'),
text='DEL',
command=button_delete,
bg='#db701f').grid(row=3,
column=3,
sticky="nsew")
# Supprimer tout
delete_all = Button(Calculatrice,
bd=5,
fg='#000',
font=('sans-serif',
20,
'bold'),
text='AC',
command=button_clear_all,
bg='#db701f').grid(row=3,
column=4,
sticky="nsew")
# Quatrième ligne
button_4 = Button(Calculatrice,
button_params_main,
text='4',
command=lambda: button_write('4')).grid(row=4,
column=0,
sticky="nsew")
button_5 = Button(Calculatrice,
button_params_main,
text='5',
command=lambda: button_write('5')).grid(row=4,
column=1,
sticky="nsew")
button_6 = Button(Calculatrice,
button_params_main,
text='6',
command=lambda: button_write('6')).grid(row=4,
column=2,
sticky="nsew")
# Multiplication
mul = Button(Calculatrice,
button_params_main,
text='*',
command=lambda: button_write('*')).grid(row=4,
column=3,
sticky="nsew")
# Division
div = Button(Calculatrice,
button_params_main,
text='/',
command=lambda: button_write('/')).grid(row=4,
column=4,
sticky="nsew")
# Cinquième ligne
button_1 = Button(Calculatrice,
button_params_main,
text='1',
command=lambda: button_write('1')).grid(row=5,
column=0,
sticky="nsew")
button_2 = Button(Calculatrice,
button_params_main,
text='2',
command=lambda: button_write('2')).grid(row=5,
column=1,
sticky="nsew")
button_3 = Button(Calculatrice,
button_params_main,
text='3',
command=lambda: button_write('3')).grid(row=5,
column=2,
sticky="nsew")
# Addition
add = Button(Calculatrice,
button_params_main,
text='+',
command=lambda: button_write('+')).grid(row=5,
column=3,
sticky="nsew")
# Soustraction
sub = Button(Calculatrice,
button_params_main,
text='-',
command=lambda: button_write('-')).grid(row=5,
column=4,
sticky="nsew")
# Sixième ligne
button_0 = Button(Calculatrice,
button_params_main,
text='0',
command=lambda: button_write('0')).grid(row=6,
column=0,
sticky="nsew")
# Le point pour les nombres décimaux
point = Button(Calculatrice,
button_params_main,
text='.',
command=lambda: button_write('.')).grid(row=6,
column=1,
sticky="nsew")
# Exposant
exp = Button(Calculatrice,
button_params_main,
text='EXP',
font=('sans-serif',
16,
'bold'),
command=lambda: button_write(E)).grid(row=6,
column=2,
sticky="nsew")
# Bouton égal
equal = Button(Calculatrice,
button_params_main,
text='=',
command=button_equal).grid(row=6,
columnspan=2,
column=3,
sticky="nsew")
# Afficher la fenetre
Calculatrice.mainloop()
# open frame
root = tk.Tk()
root.title("NOTE-IT")
root.geometry("940x600")
# create search bar
def search_text():
query = search_entry.get()
my_text.tag_remove("found", "1.0", "end")
if query:
pos = "1.0"
while True:
pos = my_text.search(query, pos, nocase=True, stopindex="end")
if not pos:
break
end_pos = f"{pos}+{len(query)}c"
my_text.tag_add("found", pos, end_pos)
pos = end_pos
# fonction imprimer
def print_text():
text_content = my_text.get("1.0", "end-1c")
printer_name = filedialog.askdirectory()
try:
with open(printer_name, "w") as printer_file:
printer_file.write(text_content)
messagebox.showinfo("impression réussi", "le texte a été imprimé avce succes!")
except Exception as e:
messagebox.showerror("erreur d'impression ", str(e))
# fonction pour changer la police
def change_font():
font_name = font.askstring("changer la police", "entrez le nom de la police:",
initialvalue=my_text["font"].split()[0])
if font_name:
my_text.config(font=(font_name, my_text["font"].split()[1]))
# change font size
def changer_police():
size = simpledialog.askinteger("Changer la taillle de la police", "enterz la taille de la police:",
initialvalue=my_text["font"].split()[1])
if size:
my_text.config(font=("Arial", size))
# open new file
def new_file():
my_text.delete("1.0", "end")
root.title('new File - Text')
status_bar.config(text="new file ")
# open file
def open_file():
my_text.delete("1.0", "end")
text_file = filedialog.askopenfilename(initialdir="C:/projet GUI/", title="open file", filetypes=(
("text files", "*.txt"), ("python Files", "*.py"), ("html", "*.html"), ("all files", "*.")))
name = text_file
status_bar.config(text=f'{name} ')
name = name.replace("c:/projet GUI/", "")
root.title(f'{name} - TextPad!')
text_file = open(text_file, 'r')
stuff = text_file.read()
my_text.insert("end", stuff)
text_file.close()
# save file
def save_as_file():
text_file = filedialog.asksaveasfilename(defaultextension=".*", initialdir="C:/projet GUI/", title="Save File",
filetypes=(
("text files", "*.txt"), ("python Files", "*.py"), ("html", "*.html"),
("all files", "*.")))
if text_file:
name = text_file
status_bar.config(text=f'saved: {name}')
name = name.replace(("c:/projet GUI/", ""))
root.title(f'{name} - TextPad!')
text_file = open(text_file, 'w')
text_file.write(my_text.get(1.0), "end")
# couleur de police
def change_color():
color = colorchooser.askcolor(title="choisir une couleur")
if color:
my_text.config(fg=color[1])
my_frame = tk.Frame(root)
my_frame.pack(pady=5)
text_scroll = tk.Scrollbar(my_frame)
text_scroll.pack(side="right", fill="y")
# open text editor
my_text = tk.Text(my_frame, width=97, height=25, font=("Helvetica", 12), selectbackground="blue",
selectforeground="black", undo=True, yscrollcommand=text_scroll)
my_text.pack()
# scroll barre
text_scroll.config(command=my_text.yview)
# set variable for open file name
global open_status_name
open_status_name = False
global selected
selected = False
# menu
my_menu = tk.Menu(root)
root.config(menu=my_menu)
# barre de recherche
search_entry = tk.Entry(root)
search_entry.pack()
# search button
search_button = tk.Button(root, text="rechercher", command=search_text)
search_button.pack()
# tag to underline founds words
my_text.tag_configure("found", background="yellow")
# menu file
file_menu = tk.Menu(my_menu)
my_menu.add_cascade(label="file", menu=file_menu)
file_menu.add_command(label="new", command=new_file)
file_menu.add_command(label="open", command=open_file)
file_menu.add_command(label="save")
file_menu.add_command(label="save as", command=save_as_file)
file_menu.add_separator()
# pour lancer l'impression
file_menu.add_command(label="impression", command=print_text)
file_menu.add_command(label="exit", command=root.quit)
# menu edit
edit_menu = tk.Menu(my_menu, tearoff=False)
my_menu.add_cascade(label="Edit", menu=edit_menu)
edit_menu.add_command(label="cut (Ctrl+x)", command=lambda: cut_text(False))
edit_menu.add_command(label="copy (Ctrl+c)", command=lambda: copy_text(False))
edit_menu.add_command(label="paste (Ctrl+v)", command=lambda: paste_text(False))
# menu option et sous menu taille , couleur et police
options = tk.Menu(my_menu, tearoff=0)
my_menu.add_cascade(label="options", menu=options)
options.add_command(label="taille de police", command=changer_police)
options.add_command(label="couleur police", command=change_color)
options.add_command(label="font police", command=change_font)
# menu outils
outils = tk.Menu(my_menu, tearoff=0)
my_menu.add_cascade(label="outils", menu=outils)
outils.add_command(label='calculatrice', command=calculatrice)
# add Status Bar to bottom of App
status_bar = tk.Label(root, text='Ready ', anchor="e")
status_bar.pack(fill="x", side="bottom", ipady=5)
# cut text
def cut_text(e):
global selected
if e:
selected = root.clipboard_get()
if my_text.selection_get():
selected = my_text.selection_get()
# delete selected text from text box
my_text.delete("sel.first", "sel.last")
# copy text
def copy_text(e):
global selected
# check to see if we used keyboard shortcuts
if e:
selected = root.clipboard_get()
if my_text.selection_get():
# grab selected text from text box
selected = my_text.selection_get()
root.clipboard_clear()
root.clipboard_append(selected)
# paste text
def paste_text(e):
global selected
# check to see if keyboard shutcut ussed
if e:
selected = root.clipboard_get()
if selected:
position = my_text.index('insert')
my_text.insert(position, selected)
root.mainloop()