Syntax-Highlight: Zeile von Wort?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Dark Shadow
User
Beiträge: 38
Registriert: Samstag 23. April 2011, 15:49

Hallo Community!
Ich arbeite gerade an einem Syntax-Highlightning-Script. Bis jetzt funktioniert es relativ gut, nur habe ich ein Problem:
Ich kann nur die erste Zeile "highlighten". Das wird durch die 1 in Zeile 23 hervorgerufen. Jetzt lautet meine Frage:

Wie kann ich die Zeile des Wortes bekommen, das gerade in der Schleife ist?

Ich habe schon festgestellt, dass das "print line" in Zeile 37 nicht ausgeführt wird. Gibt es dafür auch eine Erklärung?

Hier der Code:

Code: Alles auswählen

def highlight(key):
    thread.start_new_thread(highlight_thread, ())

def highlight_thread():
    widget = txt
    time.sleep(0.001)
    text_ = widget.get("1.0", END)
    text = text_.split()
    kws = kwlist
    kws2 = ["print", "None", "int", "str", "float"]
    hl_col = "#ff7700" #"#EF8F00"
    str_col = "#00aa00" #"#8AB218"
    kws2_col = "#900090" #IDLE-Farben
    tags = ["tg"+str(k) for k in range(len(text))]
    text_num = ""
    for tag in tags:
        try:
            widget.tag_delete(tag)
        except:
            pass
    line = 1
    for index_, word in enumerate(text):
        for kw in kws:
            if word[:len(kw)] == kw: 
                widget.tag_add(tags[index_], "%d.%d"%(line, len(text_num)), "%d.%d"%(line, len(text_num)+len(kw)))
                widget.tag_config(tags[index_], foreground=hl_col)
            elif (word.startswith("'") and word.endswith("'")) or (word.startswith('"') and word.endswith('"')):
                widget.tag_add(tags[index_], "%d.%d"%(1, len(text_num)), "%d.%d"%(1, len(text_num)+len(word)))
                widget.tag_config(tags[index_], foreground=str_col)
        for kw in kws2:
            if word[:len(kw)] == kw:
                widget.tag_add(tags[index_], "%d.%d"%(1, len(text_num)), "%d.%d"%(1, len(text_num)+len(kw)))
                widget.tag_config(tags[index_], foreground=kws2_col)
        if len(word.split("\n")) == 2:
            text_num += word + "\n"
            line += 1
            print line
        else:
            text_num += word + " "
    

from Tkinter import *
import time
import thread
from keyword import kwlist

def main():
    global txt, kwlist
    root = Tk()
    root.title("Syntax-Highlight")
    txt = Text(root)
    txt.pack()
    txt.bind("<Key>", highlight)
    root.mainloop()

if __name__ == "__main__":
    main()
Ich bedanke mich schonmal im Vorraus,
Dark Shadow
BlackJack

@Dark Shadow: Als erstes solltest Du den Thread loswerden. Man darf auf die GUI nur von dem Thread aus zugreifen, in dem die Hauptschleife läuft. Alles andere kann zu komischem Verhalten bis hin zu Abstürzen führen.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

@Dark Shadow
Ich hatte schonmal was ähnliches geschrieben http://www.python-forum.de/viewtopic.ph ... 79#p185879, müsste natürlich noch an deine Anforderungen angepasst werden. Vieleicht hilft dir das ja schonmal als Ansatz.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Dark Shadow
User
Beiträge: 38
Registriert: Samstag 23. April 2011, 15:49

Danke für eure Antworten!
Ich hab' mir Dein Skript mal angesehen, Xynon1. Habe daraus auch die Lösung mit den Zeilen gesehen und sie in abgeänderter Form übernommen. Das Ganze funktioniert jetzt relativ flüssig für mein SQL-Programm.

@BlackJack: Ich habe jetzt schon des Öfteren Multithreading verwendet und bis jetzt habe ich noch kein abnormales Verhalten feststellen können (ausser, dass es teilweise schneller war als nicht-Thread). Welches Verhalten meinst Du zum Beispiel?

Dark Shadow
BlackJack

@Dark Shadow: Alles mögliche bis hin zu harten Programmabstürzen. Das Verhalten von Tkinter (und den meisten anderen GUI-Toolkits) ist einfach undefiniert wenn man aus einem anderem als dem Thread mit der Hauptschleife auf die GUI zugreift.
Antworten