Created
November 22, 2012 09:48
-
-
Save marvin/4130284 to your computer and use it in GitHub Desktop.
tkinter with hyperlinks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# writte by joel cornett on my question on stackoverflow for having html links in message boxes | |
# http://stackoverflow.com/questions/13508043/tkinter-tkmessagebox-html-link#comment18491210_13508043 | |
# | |
import re | |
import webbrowser | |
from Tkinter import * | |
class HyperlinkMessageBox(Toplevel): | |
hyperlinkPattern = re.compile(r'<a href="(?P<address>.*?)">(?P<title>.*?)' | |
'</a>') | |
def __init__(self, master, title=None, message=None, **options): | |
Toplevel.__init__(self, master) | |
self.geometry("200x200") | |
self.title(title or master.title()) | |
self.text = Text(self, wrap=WORD, bg=master.cget('bg'), | |
height=self.cget('height')) | |
self._formatHyperLink(message) | |
self.text.config(state=DISABLED) | |
self.text.pack(side=TOP, fill=X) | |
self.makeButtons() | |
def makeButtons(self): | |
Button(self, text="Ok", | |
command=lambda *a, **k: self.destroy()).pack() | |
def _formatHyperLink(self, message): | |
text = self.text | |
start = 0 | |
for index, match in enumerate(self.hyperlinkPattern.finditer(message)): | |
groups = match.groupdict() | |
text.insert("end", message[start: match.start()]) | |
#insert hyperlink tag here | |
text.insert("end", groups['title']) | |
text.tag_add(str(index), | |
"end-%dc" % (len(groups['title']) + 1), | |
"end",) | |
text.tag_config(str(index), | |
foreground="blue", | |
underline=1) | |
text.tag_bind(str(index), | |
"<Enter>", | |
lambda *a, **k: text.config(cursor="hand2")) | |
text.tag_bind(str(index), | |
"<Leave>", | |
lambda *a, **k: text.config(cursor="arrow")) | |
text.tag_bind(str(index), | |
"<Button-1>", | |
self._callbackFactory(groups['address'])) | |
start = match.end() | |
else: | |
text.insert("end", message[start:]) | |
def _callbackFactory(self, url): | |
return lambda *args, **kwargs: webbrowser.open(url) | |
if __name__ == "__main__": | |
import re | |
def dirsel(obj, search): | |
for item in dir(obj): | |
if re.search(search, item): | |
print item | |
root = Tk() | |
h = HyperlinkMessageBox(root, "My App", 'Some message <a href="http://www.google.com">Google</a>.') | |
root.mainloop() |
Hello there,
I had a problem with multiple links to.
It wont work also with the solution linked above, because the function works always with the same tag ("hyper"). In case of an iteration we have only one tag, that simply gets a new url each iteration. Different hyperlinks added in this way receive this one identical tag as well as the last url from a list.
The problem was already solved by martineau from stak overflow. So based on the solution I made a small function that works fine for me.
https://github.com/ShukhratSobich/python-functions/blob/main/hyperlink%20into%20tk.Text
I hope this information will help somebody.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After changing a few things to work with Python 3 (
tkinter
instead ofTkinter
for starters), I found this works, but just doesn't work well.Firstly, by default, after the first link in the message, it doesn't end the hyperlink tag, so text continues to have the underline and be part of the hyperlink. I changed the last
"end",
intag_add
, to"end-%dc" % 1,
to get it to display correctly.Secondly, if there's multiple links, the
for
loop just overrides all the previous links with thewebbrowser.open(url)
of the lasturl
in themessage
. So all the links will just point to the same webpage.I don't know how to fix this, so I ended up using another Hyperlink implementation here (adapted for Python 3): https://github.com/ChristianLowe/Grognaks-Mod-Manager/blob/master/lib/tkHyperlinkManager.py
This comment is just so anyone happening to stumble upon it in 2020 is aware of the state of this
tkinter-hyperlinks.py
and hopefully doesn't waste as much time as I did trying to get it to work.