Seite 1 von 1

Syntax-Highlight: Zeile von Wort?

Verfasst: Sonntag 15. Mai 2011, 15:43
von Dark Shadow
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

Re: Syntax-Highlight: Zeile von Wort?

Verfasst: Sonntag 15. Mai 2011, 17:02
von 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.

Re: Syntax-Highlight: Zeile von Wort?

Verfasst: Montag 16. Mai 2011, 08:28
von Xynon1
@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.

Re: Syntax-Highlight: Zeile von Wort?

Verfasst: Dienstag 17. Mai 2011, 20:04
von Dark Shadow
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

Re: Syntax-Highlight: Zeile von Wort?

Verfasst: Dienstag 17. Mai 2011, 21:25
von 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.