diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bee8a64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+__pycache__
diff --git a/editor.py b/editor.py
index 41fdd47..46b21be 100644
--- a/editor.py
+++ b/editor.py
@@ -71,34 +71,45 @@ save_bt.grid(column=0, row=0, sticky=(tk.W))
open_bt = ttk.Button(toolbar, text="Ouvrir")
open_bt.grid(column=1, row=0, sticky=(tk.W))
+old_text = ""
def diff(old, new):
+ if old == new:
+ return None
index = 0
- line = 1
- char = 0
for i in range(min(len(old), len(new))):
if old[i] != new[i]:
return {
"type": "replace",
- "start": str(line)+"."+str(char),
- "end": 0,
+ "start": "1.0+"+str(i)+"c",
+ "end": "1.0+"+str(i+abs(len(old) - len(new))-1)+"c",
"text": new[i:i+abs(len(old)-len(new))]
}
- char += 1
- if old[i] == "\n":
- line += 1
- char = 0
- return {
- "type": "insert",
- "start": "end",
- "text": new[i:i+abs(len(old)-len(new))]
- }
+ if len(old) > len(new):
+ return {
+ "type": "replace",
+ "start": "end-"+str(len(old)-len(new))+"c",
+ "end": "end",
+ "text": ""
+ }
+ else:
+ return {
+ "type": "insert",
+ "start": "end",
+ "text": new[len(old):]
+ }
def on_area_input(event):
+ global old_text
#print(area.get("1.0", "end"))
print(event)
#sock.send({"type":"insert", "start":"1.0", "text":area.get("1.0", "end")}, send_addr)
- sock.send({"type":"replace", "start":"1.0", "end":"end", "text":area.get("1.0", "end")}, send_addr)
+ #sock.send({"type":"replace", "start":"1.0", "end":"end", "text":area.get("1.0", "end")}, send_addr)
+ d = diff(old_text, area.get("1.0","end"))
+ if d == None:
+ return
+ sock.send(d, send_addr)
+ old_text = area.get("1.0","end")
#if event.keycode == 25:
# area.mark_set("insert", "1.0")
@@ -106,18 +117,23 @@ def on_area_input(event):
area.bind("
print(area.get("1.0", "end")) # obtenir tout le texte
print(area.get("2.0", "8.0")) # le texte de la ligne 2 à la ligne 8
area.replace("1.0", "end", "le nouveau texte") # remplacer du texte
-area.insert("1.0", "le nouveau texte") # insérer du textePour mettre en forme certaines parties du texte, on peut utiliser des +tags :
+area.tag_configure("fond_rouge", background="#ffaaaa")
+area.tag_configure("insistance", foreground="#008800", underline=True)
+
+area.insert("1.0", "ce texte sera sur fond rouge", "fond_rouge")
+text.tag_add("insistance", "1.3", "1.8")Liste de tous +les styles possibles.
Certains widgets (Text) peuvent défiler avec la molette,
mais pour afficher la barre de défilement il faut un widget
supplémentaire.
scroll = ttk.Scrollbar(root, orient=tk.VERTICAL, command=mon_widget_qui_défile.yview)
-scroll.grid(column=1, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
-mon_widget_qui_défile.configure(yscrollcommand=scroll.set)scroll = ttk.Scrollbar(root, orient=tk.VERTICAL, command=mon_widget_qui_défile.yview)
+scroll.grid(column=1, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
+mon_widget_qui_défile.configure(yscrollcommand=scroll.set)Un cadre qui peut avoir une bordure et contenir d’autres widgets.
-frame = ttk.Frame(root, borderwidth=5, relief="ridge", width=200, height=100)frame = ttk.Frame(root, borderwidth=5, relief="ridge", width=200, height=100)Les options ne sont pas obligatoires.
Le cadre contient ses propres lignes et colonnes. Pour placer des
widgets dedans, il suffit de remplacer root par
frame en les créant.
La barre de menus en haut de la fenêtre.
-root.option_add('*tearOff', False)
-menubar = tk.Menu(root)
-root['menu'] = menubar
-
-menu_file = tk.Menu(menubar)
-menu_edit = tk.Menu(menubar)
-
-menubar.add_cascade(menu=menu_file, label='Fichier')
-menubar.add_cascade(menu=menu_edit, label='Édition')
-
-menu_file.add_command(label='Ouvrir', command=on_open)root.option_add('*tearOff', False)
+menubar = tk.Menu(root)
+root['menu'] = menubar
+
+menu_file = tk.Menu(menubar)
+menu_edit = tk.Menu(menubar)
+
+menubar.add_cascade(menu=menu_file, label='Fichier')
+menubar.add_cascade(menu=menu_edit, label='Édition')
+
+menu_file.add_command(label='Ouvrir', command=on_open)Le canevas est une zone de dessin.
-canvas = tk.Canvas(root, background='white')canvas = tk.Canvas(root, background='white')On peut y dessiner des formes :
-canvas.create_line(x1, y1, x2, y2)
-canvas.create_line(x1, y1, x2, y2, fill="red", width=3, dash=6)
-canvas.create_rectangle(x1, y1, x2, y2, fill="red", outline="blue")
-canvas.create_oval(x1, y1, x2, y2, fill="red", outline="blue")canvas.create_line(x1, y1, x2, y2)
+canvas.create_line(x1, y1, x2, y2, fill="red", width=3, dash=6)
+canvas.create_rectangle(x1, y1, x2, y2, fill="red", outline="blue")
+canvas.create_oval(x1, y1, x2, y2, fill="red", outline="blue")Quand il se passe quelque chose sur un widget, un événement est généré. On peut écouter les événements de certains types, c’est-à-dire lancer une fonction quand l’action se produit.
Par exemple, on affiche des informations quand une touche du clavier est relâchée dans la zone de texte :
-text = tk.Text(root)
-
-def onrelease(event):
- print("On a frappé le clavier !")
- print(event)
-
-area.bind("<KeyRelease>", onrelease)text = tk.Text(root)
+
+def onrelease(event):
+ print("On a frappé le clavier !")
+ print(event)
+
+area.bind("<KeyRelease>", onrelease)On peut aussi utiliser les infos contenues dans l’événement, par
exemple event.keycode.
Demander où enregistrer un fichier, quel fichier ouvrir, choisir un dossier.
-from tkinter import filedialog
-
-filetypes = [
- ("Texte", "*.txt"),
- ("Image PNG", "*.png"),
- ("Autre", "*.*")
-]
-chemin = tk.filedialog.asksaveasfilename(filetypes=filetypes)
-print(chemin)from tkinter import filedialog
+
+filetypes = [
+ ("Texte", "*.txt"),
+ ("Image PNG", "*.png"),
+ ("Autre", "*.*")
+]
+chemin = tk.filedialog.asksaveasfilename(filetypes=filetypes)
+print(chemin)On peut remplacer asksaveasfilename par
askopenfilename ou askdirectory.
Demander de choisir une couleur.
-from tkinter import colorchooser
-
-color = colorchooser.askcolor(initialcolor='black')
-print(color)from tkinter import colorchooser
+
+color = colorchooser.askcolor(initialcolor='black')
+print(color)On peut aussi indiquer la couleur initiale avec sa notation
hexadécimale "#000000".