Seite 1 von 1

syntaxhighliting und Autotabs mit ScrolledText

Verfasst: Sonntag 9. November 2008, 13:30
von Andyh
Hallo

Ich stehe mal wieder auf dem Schlauch.
Es gibt hier schon zwei Beiträge zum syntaxhighliting, aber keinen Brauchbaren. Die einzige Information wo ich herausbekomme ist:
tag_add und tag_config

Nur das ich damit nicht weit gekommen bin.

Mir ist klar das es keine Funktion gibt die:
den Text sucht und ihn farbig markiert, sondern nur tags

Ich müsste ja den text suchen und die Position bestimen und dann mit tag_add den tag hinzufügen und das muss auch beim Schreiben klappen und nicht nur beim einlesen einer Datei.

Hat jemand einen Guten link oder eine Idee?

Gruß
Andyh

Verfasst: Sonntag 9. November 2008, 13:49
von BlackJack
Schau Dir an wie IDLE das implementiert hat.

Verfasst: Sonntag 9. November 2008, 14:00
von Andyh
Hallo

Sehe ich so Blöd aus (achso du hast mich ja noch nicht gesehen) :D

Ich schauhe jetzt schon den Halben tag an wie die das machen, aber es ist nicht leich da überhaupt was zu verstehen.

Gruß
Andyh

Verfasst: Sonntag 9. November 2008, 17:19
von numerix
Was genau ist denn dein Problem:
Die Schlüsselwörter im text-Widget zu finden?
Die gefundenen Schlüsselwörter einzufärben?
Bei Eingabe im text-Widget unmittelbar nach der Eingabe festzustellen, ob ein Schlüsselwort eingegeben wurde bzw. entstanden ist?

Das sind ja ganz unterschiedliche Dinge.

Zeig doch mal deinen Code: Was hast du bisher gemacht und was klappt nicht wie gewünscht?

Verfasst: Sonntag 9. November 2008, 18:29
von Andyh
Hallo

Es gibt leider noch keinen code. Ich veruche immer erst Probleme zu lösen und schreibe ich das ganze Programm.

Ich habe es mit dem grundgerüst versucht:

Code: Alles auswählen

lass Fenster():
    def __init__(self, l):
        self.l = l
        self.root = tk.Tk()
        self.root.title("Pyedit 1.0")
        self.root.geometry("600x700")
        self.root.frame = tk.Frame(self.root)
        self.root.frame.pack(expand=tk.YES, fill=tk.BOTH)
        self.datei = "Hallo"
        self.root.bind("<F5>", lambda e: self.l.ausf(self.datei))
        
        self.sc=ScrolledText(self.root.frame,  
                highlightbackground='#0099e0', 
                highlightthickness=1, relief=tk.FLAT, wrap =tk.WORD)
        
        self.sc.pack()
        
        self.sc.tag_configure("a", background="yellow", foreground="red")
        self.sc.insert(tk.END, "hallo\n", "a")
        self.sc.insert(tk.END, "hallo\n", "a")
        self.sc.insert(tk.END, "hallo\n", "a")
        self.sc.insert(tk.END, "hallo\n", "a")
        
        
    def start(self):
        self.root.mainloop()

class Logic():
    def __init__(self):
        pass

    def ausf(self, datei):
        print datei
    
if __name__ == "__main__":
    l = Logic()
    fenster = Fenster(l)
    fenster.start()

else:
    "ERROR: Kein Modul"
"bind" habe ich auch noch ausprobiert.
Mein Problem ist genau alles was du Aufgezählt hast.

Gruß
Andyh

Verfasst: Montag 10. November 2008, 18:00
von numerix
Ich meine, etwas Lektüre in der Tkinter-Doku hätte da helfen sollen ...

Zur Weiterarbeit und Inspiration:

Code: Alles auswählen

import Tkinter as tk

class Editor(tk.Text):

    KEYWORDS = ['print','import','from']
    KEYCOLOR = "red"

    def __init__(self,args):
        tk.Text.__init__(self,args)
        self.config(background="white")
        self.bind("<KeyRelease>",self.contentcheck)
        self.focus_set()

    def contentcheck(self,event):
        self.tag_delete("keyword")
        self.tag_config("keyword",foreground=Editor.KEYCOLOR)
        for keyword in Editor.KEYWORDS:
            pos = "1.0"
            while pos:
                pos = self.search(keyword,pos,stopindex="end")
                if pos:
                    newpos = pos+"+%ic" %len(keyword)
                    self.tag_add("keyword",pos,newpos)
                    pos = newpos

root = tk.Tk()
editor = Editor(root)
editor.pack()
root.mainloop()
Im Prinzip ist hier alles drin, was du wolltest, als Grundgerüst(!).

Was noch fehlt - damit noch was für dich bleibt - ist die Feinarbeit, so dass die Schlüsselwörter auch wirklich nur dann hervorgehoben werden, wenn sie als eigenständige Wörter (und nicht als Bestandteil anderer Wörter) vorkommen oder innerhalb von Strings oder in Kommentaren etc.

Die Unterscheidung verschiedener Typen von Schlüsselwörtern und verschiedener Farben etc. lässt sich leicht ergänzen.

Was ich nicht ausprobiert habe, ist, ob die Performance bei dieser Art der Implementation noch ausreicht, wenn der Inhalt im Editor länger und/oder die Anzahl der Schlüsselwörter deutlich größer wird. Falls nicht, müsste man einen anderen Weg beschreiten, indem man nur gezielt an den Änderungen arbeitet und nicht immer den ganzen Inhalt neu durchpflügt.

Verfasst: Montag 10. November 2008, 18:07
von Andyh
Hallo

Ich könnte mich und meine Gehirn echt schlagen.

Das ich auf "self.bind("<KeyRelease>",self.contentcheck)" nicht gekommen bin, jetzt müsste es ein leichtes sein!!!

Doppel mega Danke Gruß
Andy

Verfasst: Montag 10. November 2008, 18:23
von numerix
Andyh hat geschrieben:jetzt müsste es ein leichtes sein!!!
Kommt drauf an, wie gut es funktionieren soll.

Wie schon gesagt: Wenn der Inhalt zu lang und/oder die Anzahl der Schlüsselwörter zu groß wird, befürchte ich Performance-Probleme mit diesem Ansatz.

Und: Du musst z.B. noch feststellen, ob ein Schlüsselwort in einer Zeichenkette oder einem Kommentar steht. Da wird die ein oder andere Hürde noch zu nehmen sein.

Verfasst: Freitag 14. November 2008, 19:29
von Andyh
Hallo

@numerix
Nochmals vielen Dank, das so einen Doofy wie mir hilft!

Jetzt wo das syntaxhighliting recht gut geht kommt auch schon das nächste Problem das bei einem ":" eingerückt wird und bei "return" wieder zurück gesprungen wird.

Das ist an sich nicht schwer, ich hatte so einen Ansatz (der code ist leider schon wieder weg):

erst wird die Taste "ENTER" mit eine Funktion verknüpft
und dann wird beim syntaxhighliting das so gemacht
Wenn Keyword == ":"
dann wird eine Variable um 4 erhöht
beim Nächsten enter werden so viel leerzeichen eingefügt wie die Variable enthält

und bei "return" das gleiche nur anders rum.

Nur das geht nicht wenn ich wieder plötzliche mit dem Cursor wo anders Positioniere.

Ich bin mir diesmal sicher das es nicht mit tag´s geht und wenn dann nur sehr umständlich.

Ich finde Programmieren gerade wegen solchen kniffligen Problemen Interessant, nur wenn man die halbe Woche rum macht und es nichts wird verliert man den spaß.

Gruß
Andyh

Verfasst: Freitag 14. November 2008, 21:14
von numerix
Für den Einstieg und zur Inspiration:

Code: Alles auswählen

import Tkinter as tk

class Editor(tk.Text):

    def __init__(self,args):
        tk.Text.__init__(self,args)
        self.config(background="white")
        self.bind("<KeyRelease-Return>",self.indentcheck)
        self.focus_set()

    def indentcheck(self,event):
        pos = self.index("insert")
        row = int(pos.split(".")[0])-1
        line = self.get("%i.0" %row,"%i.end" %row).rstrip()
        indent = len(line)-len(line.lstrip())
        if line.endswith(":") and not line.lstrip().startswith('#'):
            indent += 4
        self.insert(pos,indent*" ")

root = tk.Tk()
editor = Editor(root)
editor.pack()
root.mainloop()

Verfasst: Samstag 15. November 2008, 09:18
von Andyh
Hallo

Das ist ja mal wieder ginal!!!

Gruß
Andyh