Notebook word make clickable

Hello,
I’m trying to figure out how to make a certain word string clickable from a notebook page.
It’s currently setup as follows: Panel -> notebook -> notebookpage(“panel”) -> which contains a list of sentences stored using TextCtrl.
The goal is to have certain words from those different sentences made clickable, so can catch that click event and do some stuff (like, launch another program).
I did some digging but still not sure what would be the approach here.
Your help is greatly appreciated.
Thank you

You would use one of the button controls, or else a html ctrl.

Karsten

Hi Karsten,
Thank you for you reply. Could you please elaborate on your answer if possible, maybe you have an snippet example?
Having the structure above and a list of sentences, how would I use the button control on certain words ?
Thank you

You would have to split the text appropriately, and
intersperse textctrls and buttons as needed, perhaps using a
flowsizer.

Karsten

Hi Karsten,
This text data can also be rather large files. Would this be feasible from performance perspective as well?
Can you reference a good example for flowsizer and perhaps an example that intersperses txtctrls and buttons?
Thank you

Wouldn’t it be simpler to just grab the word under the mouse pointer and do a normal python search of your word list to determine if special action should be taken?

Inspired by a similar issue in Stack Overflow, I wrote a word-clicking program that might give some helpful hints:

import wx

sample_text = """Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
eprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum."""

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 'Word Clicker')
        pnl = wx.Panel(self, wx.ID_ANY)
        lbl = wx.StaticText(pnl, wx.ID_ANY, "Source Text")
        self.richText = txt = wx.TextCtrl(
            pnl,
            wx.ID_ANY,
            sample_text,
            style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.TE_READONLY,
        )
        self.found = fnd = wx.StaticText(pnl, wx.ID_ANY, "<result goes here>")
        txt.Bind(wx.EVT_LEFT_DOWN, self.OnGetWord)
        txt.SetInsertionPoint(0)
        txt.SetCursor(wx.Cursor(wx.CURSOR_HAND))
        szr = wx.BoxSizer(wx.VERTICAL)
        szr.AddMany([(lbl,0),(txt,1,wx.EXPAND), (fnd,0,wx.EXPAND)])
        pnl.SetSizerAndFit(szr)


    def OnGetWord(self, event):
        xy_pos = event.GetPosition()
        _, word_pos = self.richText.HitTestPos(xy_pos)
        search_text = self.richText.GetValue()
        left_pos = right_pos = word_pos
        if word_pos < len(search_text) and search_text[word_pos].isalnum():
            try:
                while left_pos >= 0 and search_text[left_pos].isalnum():
                    left_pos -= 1
                while right_pos <= len(search_text) and search_text[right_pos].isalnum():
                    right_pos += 1
                found_word = search_text[left_pos + 1 : right_pos]
                print(f"Found: '{found_word}'")
            except Exception as e:
                found_word = "<" + str(e) + ">"
        else:
            found_word = "<Not On Word>"
        self.found.SetLabel(found_word)

if __name__ == '__main__':
    app = wx.App()
    MyFrame().Show()
    app.MainLoop()

1 Like

Hello Rufus,
Thank you very much for taking the time to answer.
This is great solution and it works.
Given the sample_text above would you know if it’s possible to highlight | underline certain words that I would know in advance which ones need to be emphasized? For ex. I know I want to highlight/underline the words ‘labore’ and ‘fugiat’?
Thank you