This is what I am trying to do:
I create a window and there is text that is displayed on it, as a user I click on the text,
example: the displayed text is.
'Hello World, I am a Python program.'
So if the user clicks words, I want it to generate an event and it would go into a function and I want to do something in the function (like changing the color of that word, so I also need to track which word I clicked)
I am not so sure how to do that, I could potentially make each word a button but that would be ugly.
import wx
def SomeListener(evt):
print "Got Event:",evt
print "My XY:",evt.GetX(),evt.GetY()
#youll have to figure out which word you clicked using x,y (note x,y relative to static text field)
a= wx.App(redirect=False)
f = wx.Frame(None,-1)
p = wx.Panel(f,-1)
t = wx.StaticText(p,-1,"Some Text")
t.Bind(wx.EVT_LEFT_DOWN,SomeListener)
f.Show()
a.MainLoop()
or using htmlwin ... but it underlines all the words... I wasnt able to figure out how to not do that
import wx
import wx.html
def OnClickWord(e):
print "You Clicked:",e.GetLinkInfo().GetHref()
return
class MyHtmlFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title)
html = wx.html.HtmlWindow(self)
#if "gtk2" in wx.PlatformInfo:
html.SetStandardFonts()
html.SetPage(
"<style>a {text-decoration: none;color: #000; }</style>" #sorry no css support :/
"<a href=\"word1\">Word1</a> <a href=\"word2\">word 2</a> <a href=\"wizard of oz\">wizard of oz</a>.")
app = wx.PySimpleApp()
frm = MyHtmlFrame(None, "Simple HTML")
frm.Bind(wx.html.EVT_HTML_LINK_CLICKED,OnClickWord)
frm.Show()
app.MainLoop()
Joran's solution is fine if you don't mind each word looking like a bright blue underlined link.
For those interested in doing it WITHOUT blue underlined "hotlink" style text this can be accomplished in by setting up a RichText window. The code below is a code sample for this: it takes whatever you put in the "text" variable and processes it into the RichText window such that it looks like ordinary text but each word will throw an OnURL event when clicked. Neither the user nor the programmer has to worry about setting that up, just pass "text" to the URLtagger and process the OnURL calls however you want.
This example just passes the clicked word to the OnURL event, if you want unique identifiers for each word add them at the URLtagger method, note that the identifiers are wholly independent of the text shown so you can display text and receive numbers if you want.
import wx
import wx.richtext as rt
class RichTextFrame(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, *args, **kw)
self.rtc = rt.RichTextCtrl(self, style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER);
wx.CallAfter(self.rtc.SetFocus)
self.rtc.Bind(wx.EVT_TEXT_URL, self.OnURL)
def URLtagger(self, text):
for word in text.split():
self.rtc.BeginURL(word)
self.rtc.WriteText(" "+word+" ")
self.rtc.EndURL()
def OnURL(self, evt):
wx.MessageBox(evt.GetString(), "Word Clicked")
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
if rt.RichTextBuffer.FindHandlerByType(rt.RICHTEXT_TYPE_HTML) is not None:
return
rt.RichTextBuffer.AddHandler(rt.RichTextHTMLHandler())
rt.RichTextBuffer.AddHandler(rt.RichTextXMLHandler())
wx.FileSystem.AddHandler(wx.MemoryFSHandler())
self.win = RichTextFrame(self, -1, "wx.richtext.RichTextCtrl",
size=(700, 500),
style = wx.DEFAULT_FRAME_STYLE)
self.win.Show(True)
app = wx.App(0)
frame = wx.Frame(None)
panel = TestPanel(frame)
frame.Hide()
text = 'It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness.'
panel.win.URLtagger(text)
app.MainLoop()