Links (Tags) im Text Widget
Da man beim Setzen der einzelnen Tags im Text-Widget die Anfangs- und Endpositionen ohnehin explizit in der Form "x.y" angeben muss, könnte man diese einfach in einer Liste ablegen und darauf dann zugreifen, statt die Methode tag_ranges zu verwenden, die hier die Probleme bereitet.
@numerix: Ja so funktioniert es einwandfrei. Mich nimmt es wirklich Wunder ob ich der einzige in diesem Forum bin der mit diesem Problem konfrontiert ist.
Hallo gibt es in unserem Forum Leute, welche gleiche Probleme mit dem Code-Snippet hatten wie ich?
Danke für jede Antwort.
Gruss an alle
Hallo gibt es in unserem Forum Leute, welche gleiche Probleme mit dem Code-Snippet hatten wie ich?
Danke für jede Antwort.
Gruss an alle
Take it easy Mates!
Bei mir hinterlässt die Sache auch ein ungutes Gefühl, bedeutet es doch auch, dass ich damit rechnen muss, dass ein Tkinter-Programm, das auf (m)einem Rechner sauber läuft und keine externen Abhängigkeiten hat, möglicherweise auf einem anderen Rechner nicht läuft, obwohl dort - dem Anschein nach - die gleiche Python-Umgebung installiert ist.wuf hat geschrieben:@numerix: Ja so funktioniert es einwandfrei. Mich nimmt es wirklich Wunder ob ich der einzige in diesem Forum bin der mit diesem Problem konfrontiert ist.
So etwas habe ich im Zusammenhang mit Tkinter bisher erst ein einziges Mal an einem weniger gravierenden Beispiel erlebt (http://www.python-forum.de/topic-15674.html)
Unter meinem Python 2.5.2 läufts einwandfrei
(mit den Zeilen und Spaltenindizes als Strings).
Unter 3.0 hab' ich das gleiche Problem wie wuf:
Mehr fällt mir da im Moment auch nicht ein.
yipyip
(mit den Zeilen und Spaltenindizes als Strings).
Unter 3.0 hab' ich das gleiche Problem wie wuf:
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/local/lib/python3.0/tkinter/__init__.py", line 1405, in __call__
return self.func(*args)
File "linktext3.py", line 8, in klick
index = bisect(tagposlist, klickpos)
TypeError: unorderable types: str() < _tkinter.Tcl_Obj()
Python 3.0 (r30:67503, Dec 4 2008, 13:25:00)
yipyip
Hallo yipyip
Danke für deine Versuche. Da WINDOWS VISTA auf meinem Laptop verfügbar ist installierte ich auch noch Python 3.0 unter diesem OS. Stellte das gleiche Fehlverhalten fest. Ich sehe meine Zukunft wird wieder mit viel Spielereien und Zeitvergeudung belastet Es lebe der Wechsel zu Python 3.0
P.S. Nachträgliche Feststellung: '2to3' entschärft die Sache doch schon ein wenig.
Viel Vergnügen an alle Spielkameraden. Gruss wuf
Danke für deine Versuche. Da WINDOWS VISTA auf meinem Laptop verfügbar ist installierte ich auch noch Python 3.0 unter diesem OS. Stellte das gleiche Fehlverhalten fest. Ich sehe meine Zukunft wird wieder mit viel Spielereien und Zeitvergeudung belastet Es lebe der Wechsel zu Python 3.0
P.S. Nachträgliche Feststellung: '2to3' entschärft die Sache doch schon ein wenig.
Viel Vergnügen an alle Spielkameraden. Gruss wuf
Take it easy Mates!
..... Hier ein Lösungsansatz für das Problem:
Gruss wuf
Code: Alles auswählen
# Python 3.0
import tkinter as tk
from bisect import bisect
def klick(e):
tagposlist = [str(tag_pos) for tag_pos in list(text.tag_ranges("link"))]
klickpos = text.index(tk.CURRENT)
index = bisect(tagposlist,klickpos)
print(index, tagposlist, klickpos, end=" -> ")
print(text.get(tagposlist[index-1],tagposlist[index]))
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.insert("0.0","Das ist ein Mustertext, man kann auf Klick drücken!")
text.tag_add("link","1.37","1.42")
text.tag_add("link","1.12","1.22")
text.tag_config("link",background="green")
text.tag_bind("link","<Button-1>",klick)
root.mainloop()
Take it easy Mates!
Ich hatte schon vermutet, dass man die textindex-Objekte via str() in die gewünschte Form bringen kann, konnte es aber in Ermangelung dieser Objekte nicht testen. Danke dafür.
Die explizite Umwandlung in eine Liste via list() in der LC scheint mir überflüssig. Testen kann ich es nicht.
Die explizite Umwandlung in eine Liste via list() in der LC scheint mir überflüssig. Testen kann ich es nicht.
Hallo,
Danke, hatte das durchdacht und bemerkt, dass ein einzelner Tag die vielen Tags ersetzen würde und den gleichen Job ausführt. Nun habe ich meinen Code verändert und bemerkt, dass wenn ich meine Maus über den Link bewege, alle Links im Text unterstrichen angezeigt werden, da ich den Tag an ein Event gebunden habe, der eine Funktion aufruft, der genau das tut... Aber natürlich, denn beide Links verwenden den selben Tag... Würde ich das weglassen, würde es generell gehen... Will ich aber nicht^^ Deswegen werde ich die Tag Benennung doch lassen
Danke für den Code, der nun bewirkt, dass ich herausfinden kann, welcher Link angeklickt wurde! Hat mir sehr geholfen!
Nun aber noch eine Frage:
Wenn man mit der Maus über den Link scrollt, soll er unterstrichen werden. Gemacht habe ich das mit einem Event, das an eine Funktion gebunden ist, die dann ausgeführt wird. Problem: Woher soll die Funktion wissen, über welchen Link gescrollt wird, damit sie ihn dann unterstreichen kann?
Grüße Markus
Danke, hatte das durchdacht und bemerkt, dass ein einzelner Tag die vielen Tags ersetzen würde und den gleichen Job ausführt. Nun habe ich meinen Code verändert und bemerkt, dass wenn ich meine Maus über den Link bewege, alle Links im Text unterstrichen angezeigt werden, da ich den Tag an ein Event gebunden habe, der eine Funktion aufruft, der genau das tut... Aber natürlich, denn beide Links verwenden den selben Tag... Würde ich das weglassen, würde es generell gehen... Will ich aber nicht^^ Deswegen werde ich die Tag Benennung doch lassen
Danke für den Code, der nun bewirkt, dass ich herausfinden kann, welcher Link angeklickt wurde! Hat mir sehr geholfen!
Nun aber noch eine Frage:
Wenn man mit der Maus über den Link scrollt, soll er unterstrichen werden. Gemacht habe ich das mit einem Event, das an eine Funktion gebunden ist, die dann ausgeführt wird. Problem: Woher soll die Funktion wissen, über welchen Link gescrollt wird, damit sie ihn dann unterstreichen kann?
Grüße Markus
Geht im Prinzip genauso. Du musst halt zusätzlich die Events "Enter" und "Leave" binden und entweder mit drei Handlern arbeiten oder mit einem, der anhand des Event-Types feststellt, welches Event den Handler aufgerufen hat. Das sähe dann so aus (läuft so unter 2.x und 3.0):Markus12 hat geschrieben:Wenn man mit der Maus über den Link scrollt, soll er unterstrichen werden. Gemacht habe ich das mit einem Event, das an eine Funktion gebunden ist, die dann ausgeführt wird. Problem: Woher soll die Funktion wissen, über welchen Link gescrollt wird, damit sie ihn dann unterstreichen kann?
Code: Alles auswählen
if __import__("sys").version_info[0] == 3:
import tkinter as tk
else:
import Tkinter as tk
from bisect import bisect
def handler(e):
tagpositions = [str(pos) for pos in text.tag_ranges("link")]
mouseposition = text.index(tk.CURRENT)
index = bisect(tagpositions, mouseposition) # ACHTUNG: Zeile muss ersetzt werden -> siehe Beitrag unten!
linkposition = tagpositions[index-1:index+1]
if e.type == "7": # <Enter>
text.config(cursor="hand1")
text.tag_add("tmp", *linkposition)
text.tag_config("tmp", underline=True)
elif e.type == "8": # <Leave>
text.config(cursor="")
text.tag_delete("tmp")
elif e.type == "4": # <Button-1>
print(text.get(*linkposition))
root = tk.Tk()
text = tk.Text(root)
text.pack(padx=5, pady=5)
text.insert("0.0","Das ist ein Mustertext, man kann auf Klick drücken!")
text.config(bg="white", state="disabled")
text.tag_add("link","1.37","1.42")
text.tag_add("link","1.12","1.22")
text.tag_config("link",foreground="blue")
text.tag_bind("link","<Button-1>", handler)
text.tag_bind("link","<Enter>", handler)
text.tag_bind("link","<Leave>", handler)
root.mainloop()
Zuletzt geändert von numerix am Freitag 16. Januar 2009, 11:23, insgesamt 1-mal geändert.
Hey,
danke! Das Attribut type hatte ich gar nicht gekannt, wieder was gutes dazu gelernt
Dachte auch nicht, dass das mit text.index und Current funktioniert, wenn man nicht in den Text klickt... Interessant =) Das löst mein Problem.
nun gibt es aber noch etwas unerwartetes, aber behebbares.
Wenn man bisect die beiden indexwerte in einer liste gibt und dann noch den Index, wo man geklickt hat, kann und wird es oft zu Fehlern kommen. Warum? Die Liste, die die Funktion intern berechnet, sortiert die Liste natürlich und schaut dann, wo das zweite Argument (wo man geklickt hatte) in der Liste sein würde und gibt diesen Index zurück.
Dieses Beispiel beschreibt diesen Fall ganz gut:
tagposlist = ["1.4", "1.9"]
geklickt = "1.33"
bisect intern = ["1.33", "1.4", "1.9"]
Natürlich, denn die Argumente sind ja Strings, und somit werden die von Anfang an durchgegangen und dann sortiert. Da die 3 aber vor der 4 vorkommt, wird "1.33" natürlich auch an den Anfang gestellt... Was für den gesamten Programmlauf bedeuten würde, dass in meinem Programm immer ein falscher oder immer die falsche Linkfunktion ausgeführt werden würde
Kann man beheben, indem man die spalte (33, 4 und 9) zu Zahlen konvertiert und da dann noch mit herumspielt...
Grüße Markus
danke! Das Attribut type hatte ich gar nicht gekannt, wieder was gutes dazu gelernt
Dachte auch nicht, dass das mit text.index und Current funktioniert, wenn man nicht in den Text klickt... Interessant =) Das löst mein Problem.
nun gibt es aber noch etwas unerwartetes, aber behebbares.
Wenn man bisect die beiden indexwerte in einer liste gibt und dann noch den Index, wo man geklickt hat, kann und wird es oft zu Fehlern kommen. Warum? Die Liste, die die Funktion intern berechnet, sortiert die Liste natürlich und schaut dann, wo das zweite Argument (wo man geklickt hatte) in der Liste sein würde und gibt diesen Index zurück.
Dieses Beispiel beschreibt diesen Fall ganz gut:
tagposlist = ["1.4", "1.9"]
geklickt = "1.33"
bisect intern = ["1.33", "1.4", "1.9"]
Natürlich, denn die Argumente sind ja Strings, und somit werden die von Anfang an durchgegangen und dann sortiert. Da die 3 aber vor der 4 vorkommt, wird "1.33" natürlich auch an den Anfang gestellt... Was für den gesamten Programmlauf bedeuten würde, dass in meinem Programm immer ein falscher oder immer die falsche Linkfunktion ausgeführt werden würde
Kann man beheben, indem man die spalte (33, 4 und 9) zu Zahlen konvertiert und da dann noch mit herumspielt...
Grüße Markus
Da hast du natürlich Recht. Ich hatte meine Beispielpositionen so geschickt gewählt, dass mir das nicht aufgefallen ist. Meine Lösung sähe so aus, dass man lediglich Zeile 10 durch die folgende ersetzt:Markus12 hat geschrieben:nun gibt es aber noch etwas unerwartetes, aber behebbares. Dieses Beispiel beschreibt diesen Fall ganz gut:
tagposlist = ["1.4", "1.9"]
geklickt = "1.33"
bisect intern = ["1.33", "1.4", "1.9"]
Natürlich, denn die Argumente sind ja Strings, und somit werden die von Anfang an durchgegangen und dann sortiert. Da die 3 aber vor der 4 vorkommt, wird "1.33" natürlich auch an den Anfang gestellt... Was für den gesamten Programmlauf bedeuten würde, dass in meinem Programm immer ein falscher oder immer die falsche Linkfunktion ausgeführt werden würde
Code: Alles auswählen
index = bisect([tuple(map(int,pos.split("."))) for pos in tagpositions], tuple(map(int,mouseposition.split("."))))
Danke für die Lösung, hatte mich aber gestern abend nach meinem Post noch hingesetzt und die Lösung schnell ausgearbeitet... Habe es mit List Comprehension gemacht, deine Lösung gefällt mir allerdings auch sehr gut!
So, nun ist da ein weiteres Problem... bisect macht nicht das, was es machen soll?
thema ist nebenbei die die angeklickte auswahl in der listbox.
self.links ist ein dictionary, und jeder wert zum Schlüssel (schlüssel = thema) enthält eine liste mit tuples. Jedes tuple repräsentiert den link mit einem Tag, index1, index2, und verlinke zu Thema XY.
nur, damit ihr das nachvollziehen könnt.
Wenn es funktioniert, werde ich die verschiedenen Tags entfernen, was den Code auch schöner macht.
Was der Fehler ist? Also, erstmal unterstreicht es immer den falschen link, was sich darauf zurück führen lässt, dass etwas mit der funktion nicht stimmt.
Habe deswegen also die print befehle eingebaut.
Hier die Ausgabe:
es wird beides zweimal ausgegeben, da mein Text zwei Links enthält und die Funktion bekanntlich eine forschleife hat, die diese durchläuft und prüft.
(1, 0) ist Zeile 1, spalte 0 -> Anfang des ersten Links.
(1, 9) ist Zeile 1, spalte 9 -> Ende des Links
0 ist der Index, an dem bisect (1, 3) eingefügt hat. sollte allerdings 1 sein!
(1, 31) ist Zeile 1, spalte 31 -> Anfang von Link 2!
(1, 36) ist Zeile 1, spalte 36 -> Ende von Link 2!
0 ist der Index, und er ist korrekt.
Was mache ich falsch? Komme vielleicht einfach nur nicht drauf...
Grüße Markus
Code: Alles auswählen
p = self.text.index(CURRENT)
neuepos = [(int(p.split(".")[0]), int(p.split(".")[-1]))]
akt_links = self.links[thema]
for tag, index1, index2, zu in akt_links:
tagposliste = [(int(i.split(".")[0]), int(i.split(".")[-1])) for i in (index1, index2)]
tagposliste.sort()
a = list(tagposliste+neuepos)
a.sort()
print a
print bisect(tagposliste, neuepos)
if bisect(tagposliste, neuepos) == 1:
#do whatever
return tag
thema ist nebenbei die die angeklickte auswahl in der listbox.
self.links ist ein dictionary, und jeder wert zum Schlüssel (schlüssel = thema) enthält eine liste mit tuples. Jedes tuple repräsentiert den link mit einem Tag, index1, index2, und verlinke zu Thema XY.
nur, damit ihr das nachvollziehen könnt.
Wenn es funktioniert, werde ich die verschiedenen Tags entfernen, was den Code auch schöner macht.
Was der Fehler ist? Also, erstmal unterstreicht es immer den falschen link, was sich darauf zurück führen lässt, dass etwas mit der funktion nicht stimmt.
Habe deswegen also die print befehle eingebaut.
Hier die Ausgabe:
Code: Alles auswählen
[(1, 0), (1, 3), (1, 9)]
0
[(1, 3), (1, 31), (1, 36)]
0
(1, 0) ist Zeile 1, spalte 0 -> Anfang des ersten Links.
(1, 9) ist Zeile 1, spalte 9 -> Ende des Links
0 ist der Index, an dem bisect (1, 3) eingefügt hat. sollte allerdings 1 sein!
(1, 31) ist Zeile 1, spalte 31 -> Anfang von Link 2!
(1, 36) ist Zeile 1, spalte 36 -> Ende von Link 2!
0 ist der Index, und er ist korrekt.
Was mache ich falsch? Komme vielleicht einfach nur nicht drauf...
Grüße Markus
Ein erneutes Hallo,
Ich habe das Programm so weit nun fertig gestellt nach einer kleinen Pause, in der ich leider nicht programmieren konnte. Das Verlinken funktioniert, was noch einmal ein neues Problem aufgeworfen hatte, das ich heute erst gelöst habe...
Nun geht es allerdings darum, dass ich zwei relativ kleine Probleme habe, die ich nicht weiß zu umgehen.
1. Ich möchte das Programm starten und direkt den ersten Eintrag in der Listbox aktivieren. Mit listbox.activate funktioniert es nicht, das habe ich ausprobiert und im Web nachgelesen, und habe deshalb die Funktion listbox.selection_set(index) oder listbox.select_set(index) gefunden. Verwende ich diese in der Shell, funktioniert es auch, aber nicht im Programm...?
2. Bei Doppelklick in das Text-Widget, das den Text enthält wird der Fokus aus der Listbox entfernt, sprich, kein Eintrag in der Listbox ist angewählt. Das genau will ich verhindern; Zu jeder Zeit muss ein Eintrag angewählt sein... Die Listbox verliert den Fokus.
Das wäre das letzte zu diesem Projekt, dannach ist es endlich fertig!
Viele Grüße Markus
Danke schon mal im Voraus.
Ich habe das Programm so weit nun fertig gestellt nach einer kleinen Pause, in der ich leider nicht programmieren konnte. Das Verlinken funktioniert, was noch einmal ein neues Problem aufgeworfen hatte, das ich heute erst gelöst habe...
Nun geht es allerdings darum, dass ich zwei relativ kleine Probleme habe, die ich nicht weiß zu umgehen.
1. Ich möchte das Programm starten und direkt den ersten Eintrag in der Listbox aktivieren. Mit listbox.activate funktioniert es nicht, das habe ich ausprobiert und im Web nachgelesen, und habe deshalb die Funktion listbox.selection_set(index) oder listbox.select_set(index) gefunden. Verwende ich diese in der Shell, funktioniert es auch, aber nicht im Programm...?
2. Bei Doppelklick in das Text-Widget, das den Text enthält wird der Fokus aus der Listbox entfernt, sprich, kein Eintrag in der Listbox ist angewählt. Das genau will ich verhindern; Zu jeder Zeit muss ein Eintrag angewählt sein... Die Listbox verliert den Fokus.
Das wäre das letzte zu diesem Projekt, dannach ist es endlich fertig!
Viele Grüße Markus
Danke schon mal im Voraus.
Hallo,
wusste niemand die Antwort dazu?
Ich habe mittlerweile Problem Nummer 1 gelöst und kann mich nicht mehr daran erinnern, warum es nicht funktionierte... Zumindest tut es das nun mit ´selection_set(index)´.
Mein Problem bleibt allerdings, dass die Listbox nicht dauerhaft den Fokus hat bzw. einen Eintrag aktiviert hat. Klicke ich ins Textfeld, verliert die Listbox anscheinend den Fokus... Und das löst eine Exception aus. Selbst, wenn ich die Exception unterdrücke, was sicherlich möglich ist, ist es nicht das, was man sich vorstellt, wenn man es benutzt.
In dem Fall kann ich es nicht mehr alleine lösen... Habe verschiedene Sachen versucht und komme einfach zu keinem Ergebnis...
Ich wäre froh, wenn jemand bereits damit Erfahrung hatte und mir einen Rat geben kann oder es auch so weiß.
Viele Grüße Markus
wusste niemand die Antwort dazu?
Ich habe mittlerweile Problem Nummer 1 gelöst und kann mich nicht mehr daran erinnern, warum es nicht funktionierte... Zumindest tut es das nun mit ´selection_set(index)´.
Mein Problem bleibt allerdings, dass die Listbox nicht dauerhaft den Fokus hat bzw. einen Eintrag aktiviert hat. Klicke ich ins Textfeld, verliert die Listbox anscheinend den Fokus... Und das löst eine Exception aus. Selbst, wenn ich die Exception unterdrücke, was sicherlich möglich ist, ist es nicht das, was man sich vorstellt, wenn man es benutzt.
In dem Fall kann ich es nicht mehr alleine lösen... Habe verschiedene Sachen versucht und komme einfach zu keinem Ergebnis...
Ich wäre froh, wenn jemand bereits damit Erfahrung hatte und mir einen Rat geben kann oder es auch so weiß.
Viele Grüße Markus
Hallo Markus12
Könntest du hier vielleicht einmal ein funktionierendes Code-Snippet platzieren, welches sich wie dein Projekt verhält? Da könnten wir dein erwähntes Problem nachvollziehen und eventuell eine Lösung finden.
Gruss wuf
Könntest du hier vielleicht einmal ein funktionierendes Code-Snippet platzieren, welches sich wie dein Projekt verhält? Da könnten wir dein erwähntes Problem nachvollziehen und eventuell eine Lösung finden.
Gruss wuf
Take it easy Mates!
Damit man es versteht, denke ich, sollte ich einfach das gesamte Skript platzieren bzw. auslagern, obwohl ich nicht weiß, wo man sowas macht... Deshalb setze ich ihn hier hinein und wenn er euch zu viel ist, bitte auslagern!
Mein Code (209 Zeilen):
Viele Grüße Markus
Mein Code (209 Zeilen):
Code: Alles auswählen
from Tkinter import*
from ScrolledText import*
import time
import pickle
hauptseite= """Willkommen in der Dokumentation.
Auf der linken Seite finden Sie ein Eingabefeld, in welches Sie Wörter eingeben können, deren Definition suchen.
Bei jedem weiteren Buchstaben, den sie eingeben, wird bereits nach Themen gesucht, die ihr Schlüsselwort enthalten."""
start_tags = [("1.0", "1.32", {"font": ("Arial",12,"bold")})]
class Dokumentation(Tk):
def __init__(self):
self.__titel = []
self.datenbank = {}
self.links = {}
Tk.__init__(self)
self.title("Nachschlagen von Wörtern")
self.frame1 = Frame(self)
self.frame1.pack(side="left", fill="y")
self.l1 = Label(self.frame1, font=("Arial", 20, "bold"), text="Dokumentation")
self.l1.pack(padx=5, pady=10)
self.b = Label(self.frame1, font=("Arial", 12, "italic"), text="Schlüsselwort eingeben")
self.b.pack()
self.e = Entry(self.frame1, font=("Comic", 12, "bold"))
self.e.pack(fill="x", padx=10, pady=5)
self.e.bind("<Any-KeyRelease>", self._filtern)
self.listbox = ScrolledBox(self.frame1, height=10, font=("Times", 12))
self.listbox.pack(fill="both", padx=10, pady=10, expand=1)
self.listbox.bind("<ButtonRelease-1>", self._handler_anzeigen)
self.listbox.bind("<KeyRelease-Up>", self._handler_anzeigen)
self.listbox.bind("<KeyRelease-Down>", self._handler_anzeigen)
self.frame2 = Frame(self)
self.frame2.pack(side="right", expand=1, fill="both")
self.text = ScrolledText(self.frame2, width=30, height=14, bg="lightgrey", font=("Arial", 12), wrap="word", relief="ridg", cursor="hand1", padx=7, pady=7)
self.text.pack(padx=10, pady=10, fill="both", expand=1)
self.text.insert(END, hauptseite)
self.text.config(state="disabled")
for a,e,format in start_tags:
self.text.tag_add("start", a, e)
self.text.tag_config("start", format)
def neuesThema(self, titel, beschreibung):
self.listbox.delete(0, END)
#self.titel.append(titel)
self.datenbank[titel] = beschreibung
#self.titel.sort()
for i in self.titel:
self.listbox.insert(END, i)
def neuerLink(self, thema, index1, index2, verlinke_zu):
assert verlinke_zu in self.titel
tag = "link"+str(len(self.links)+1)
if thema in self.links:
self.links[thema] = self.links[thema]+[(tag, index1, index2, verlinke_zu)]
else:
self.links[thema] = [(tag, index1, index2, verlinke_zu)]
def anzeigen(self, thema):
self.listbox.selection_clear(0, END)
index = self.index(thema, self.listbox.get(0,END))
if index!=None: self.listbox.select_set(index)
self.text.config(state="normal")
self.text.delete("0.0", END)
self.text.insert(END, self.datenbank[thema])
self.text.config(state="disabled")
if thema in self.links:
for link in self.links[thema]:
tag, i1, i2, zu = link
self._linkanzeigen(tag, i1, i2)
def _linkanzeigen(self, tagname, index1, index2):
self.text.tag_add(tagname, index1, index2)
self.text.tag_config(tagname, foreground="blue")
self.text.tag_bind(tagname, "<Button-1>", self._handler)
self.text.tag_bind(tagname, "<Enter>", self._handler)
self.text.tag_bind(tagname, "<Leave>", self._handler)
def _handler_anzeigen(self, e):
if self.listbox.get(0, END):
self.anzeigen(self.thema)
def _handler(self, e):
tag = self._linkwahl(self.thema)
if e.type == "4": #Button-1
e.type = "8"
self._handler(e)
self.text.tag_unbind(tag, "<Leave>")
self.verlinken(tag)
elif e.type == "7": #Enter
self.text.config(cursor="hand2")
self.text.tag_config(tag, underline=1)
elif e.type == "8": #Leave
self.text.config(cursor="hand1")
self.text.tag_config(tag, underline=0)
def _linkwahl(self, thema):
links = self.links[thema]
k = self.text.index(CURRENT)
position = (int(k.split(".")[0]), int(k.split(".")[-1]))
for tag, i1, i2, zu in links:
tagposliste = [(int(i.split(".")[0]), int(i.split(".")[-1])) for i in (i1, i2)]
wahlliste = tagposliste + [position]
wahlliste.sort()
if wahlliste[1] == position:
break
return tag
def _filtern(self, event):
wort = self.e.get()
erg = [a for a in self.titel if wort in a]
self.listbox.delete(0, END)
for i in erg:
self.listbox.insert(END, i)
def verlinken(self, tag):
links = self.links[self.thema]
for tag2,i1,i2,zu in links:
if tag2 == tag:
break
self.anzeigen(zu)
def sichern(self, dateiname):
f = file(dateiname+".db", "w")
pickle.dump(self.datenbank, f)
f.close()
def laden(self, dateiname):
f = file(dateiname+".db", "r")
self.datenbank = pickle.load(f)
f.close()
self.titel = self.datenbank.keys()
self.listbox.delete(0, END)
for i in self.titel:
self.listbox.insert(END, i)
def index(self, thema, liste):
erg = None
for i in range(len(liste)):
if liste[i] == thema:
erg = i
break
return erg
def _getThema(self):
nummer = int(self.listbox.curselection()[0])
return self.listbox.get(nummer)
def _setThema(self, thema):
self.anzeigen(thema)
def _getTitel(self):
keys = self.datenbank.keys()
keys.sort()
return keys
thema = property(fget=_getThema, fset=_setThema)
titel = property(fget=_getTitel)
class ScrolledBox(Listbox):
def __init__(self, master, **kw):
self.frame = Frame(master)
self.frame.pack()
Listbox.__init__(self, self.frame, kw)
Listbox.pack(self, fill="both", expand=1, side="left")
self.scrollbar = Scrollbar(self.frame, command=self.yview)
self.scrollbar.pack(fill="y", side="right")
self.config(yscrollcommand=self.scrollbar.set)
methoden = Pack.__dict__.keys()
methoden += Grid.__dict__.keys()
methoden += Place.__dict__.keys()
for i in methoden:
if i[0]!="_" and i!="config" and i!="configure":
setattr(self, i, getattr(self.frame, i))
def main():
global d
daten = {"Hallo": "Begrüßung auf Deutsch.",
"Computer": "Ein anderes Wort für pc, was personal computer bedeutet.",
"Dokumentation": "Eine Erklärung für Dummies.",
"Hilfe": "Wenn man nicht weiter weiß, benötigt man die Hilfe.",
"Markus": "Ersteller dieses Tools.",
"Programm": "Ein Skript, das Befehle ausführt.",
"Python": "Eine Computersprache, in der dieses Programm geschrieben wurde und welche einfach ist.",
"Willkommen": "Eine andere Begrüßung in deutsch."}
d = Dokumentation()
for i in daten.keys():
d.neuesThema(i, daten[i])
d.neuerLink("Python", "1.36", "1.44", "Programm")
d.neuerLink("Markus", "1.17", "1.22", "Programm")
d.neuerLink("Hallo", "1.0", "1.9", "Willkommen")
if __name__=="__main__":
main()
Hallo Markus12
Danke für deine Anwort. Werde es einmal anschauen.
Vorab betreffs auslagern deines Skriptes. Die musst einfach folgende Web-Adresse aufrufen:
http://paste.pocoo.org/
Auf dieser Seite links unten musst du das Textformat aus der Listbox auswählen. In diesem Fall währe es 'Python'.
Als nächstes kopierst du deinen Skriptext in das Textfenster. Der Text erscheint als normaler Plaintext.
Dann musst du die Schaltfäche 'Paste' aktivieren. Nun wird der Text ins Python highlighted Format umgewandelt.
Das Adressfeld im Browser ändert sich wie folgt. Die Nummer 109979 hier nur ein Beispiel wird automatisch fortlaufend mit jedem umgewandelten Text generiert z.B:
http://paste.pocoo.org/show/109979/
Diese Adresse musst du in deinen Beitrag im Forum kopieren. Sie erscheint dann in blauer Farbe.
Dann sollte beim anklicken dieser Adresse automatisch dein ausgelagerter Text unter der Webseite http://paste.pocoo.org erscheinen.
Das musst du einmal ausprobieren. Das ist so wie ich es bis jetzt gemacht habe. Ist vielleicht nicht der schlauste Weg aber er funktioniert.
Gruss wuf
Danke für deine Anwort. Werde es einmal anschauen.
Vorab betreffs auslagern deines Skriptes. Die musst einfach folgende Web-Adresse aufrufen:
http://paste.pocoo.org/
Auf dieser Seite links unten musst du das Textformat aus der Listbox auswählen. In diesem Fall währe es 'Python'.
Als nächstes kopierst du deinen Skriptext in das Textfenster. Der Text erscheint als normaler Plaintext.
Dann musst du die Schaltfäche 'Paste' aktivieren. Nun wird der Text ins Python highlighted Format umgewandelt.
Das Adressfeld im Browser ändert sich wie folgt. Die Nummer 109979 hier nur ein Beispiel wird automatisch fortlaufend mit jedem umgewandelten Text generiert z.B:
http://paste.pocoo.org/show/109979/
Diese Adresse musst du in deinen Beitrag im Forum kopieren. Sie erscheint dann in blauer Farbe.
Dann sollte beim anklicken dieser Adresse automatisch dein ausgelagerter Text unter der Webseite http://paste.pocoo.org erscheinen.
Das musst du einmal ausprobieren. Das ist so wie ich es bis jetzt gemacht habe. Ist vielleicht nicht der schlauste Weg aber er funktioniert.
Gruss wuf
Take it easy Mates!
Hallo Markus12
Hier ein möglicher Lösungsansatz für das erste Problem. Direkte Selektion des ersten Listbox-Elementes beim Start des Skriptes:
http://paste.pocoo.org/show/110010/
Im Skript sind folgende Ergänzungen eingebettet:
Gruss wuf
Hier ein möglicher Lösungsansatz für das erste Problem. Direkte Selektion des ersten Listbox-Elementes beim Start des Skriptes:
http://paste.pocoo.org/show/110010/
Im Skript sind folgende Ergänzungen eingebettet:
Code: Alles auswählen
#~~ Neu wuf: Wird aufgerufen, wenn die Listbox den Fokus bekommt
self.listbox.bind("<FocusIn>", self._handler_anzeigen)
Code: Alles auswählen
#~~ Neu wuf: Selektiert das erste Element in der Listbox
d.listbox.focus_set()
d.listbox.selection_set(0)
Take it easy Mates!
Hallo Markus12
Das zweite Problem mit dem Doppel-Klick und Dreifach-Klick kann mit folgenden Anweisungen behoben werden (nur unter Linux ausgetestet):
Unmittelbar hinter der Text-Widget-Konfiguration einfügen.
Es gibt noch ein drittes Problem zu beheben. Wenn mit der Maus Text im Text-Widget selektiert wird verliert die Listbox die Selektion.
Nicht die Textselektion mit einem Doppel-Klick sondern mit folgender Selektionprozedur:
Das zweite Problem mit dem Doppel-Klick und Dreifach-Klick kann mit folgenden Anweisungen behoben werden (nur unter Linux ausgetestet):
Code: Alles auswählen
self.text.bind_class('Text', '<Double-Button-1>', lambda e: None)
self.text.bind_class('Text', '<Triple-Button-1>', lambda e: None)
Es gibt noch ein drittes Problem zu beheben. Wenn mit der Maus Text im Text-Widget selektiert wird verliert die Listbox die Selektion.
Nicht die Textselektion mit einem Doppel-Klick sondern mit folgender Selektionprozedur:
Gruss wufa) Maus auf Text im Text-Widget führen.
b) Linke Maustaste drücken und gedrückt halten
c) Maus über den Text ziehen
d) Linke Maustaste loslassen
Take it easy Mates!
Hallo Markus12
Hier ein Lösungsversuch des dritten Problems:
http://paste.pocoo.org/show/110042/
Gruss wuf
Hier ein Lösungsversuch des dritten Problems:
http://paste.pocoo.org/show/110042/
Gruss wuf
Take it easy Mates!