wxpythontextctrl

How can I bind mouse event like leftdown on one word of TextCtrl. see the code start with #?


I want bind mouse event on a word of TextCtrl when I append Text to . below is the code I write. I am not very good at English. Thanks for any help.

import wx

class TextFrame(wx.Frame):

def __init__(self):   
    wx.Frame.__init__(self, None, -1, 'Text Entry Example',   
            size=(300, 250))   
    panel = wx.Panel(self, -1)   
    richLabel = wx.StaticText(panel, -1, "Rich Text")   
    richText = wx.TextCtrl(panel, -1,   
            "If supported by the native control, this is reversed, and this is a different font.",   
            size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2)   
    richText.Bind(wx.EVT_RIGHT_DOWN, self.OnTextCtrl1LeftDown) 
    richText.SetInsertionPoint(0) 

    #? how can I bind mouse event like leftdown on Text below 
    #? how can I bind mouse event like leftdown on Text below 
    richText.SetStyle(44, 52, wx.TextAttr("white", "black"))   

    points = richText.GetFont().GetPointSize()   
    print points,type(points) 
    f = wx.Font(points + 10, wx.ROMAN, wx.ITALIC, wx.BOLD, True)   
    richText.SetStyle(68, 82, wx.TextAttr("blue", wx.NullColour, f))   

    sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)   
    sizer.AddMany([richLabel, richText])   
    panel.SetSizer(sizer) 
def OnTextCtrl1LeftDown(self,event): 
    print "clientwx,leftdown" 

Solution

  • I don't believe that there is a way to determine which word that you clicked on or hovered over in a TextCtrl.
    However, you might be able to do what you want by predefining the area that the word takes up and use the coordinates of the mouse position.
    For example: you know that the word "reserved" takes up the area between, 44 and 52 because you assign a style to it, test for that in your OnTextCtrl1LeftDown function.
    Get the mouse position and perform a HitTest using:

    m_pos = event.GetPosition()  # position tuple
    self.richText.HitTest(m_pos)
    #now code here to test if the column and row positions are within your parameters#
    

    HitTest finds the row and column of the character at the specified point.

    Edit: Here's your code modified:
    Note: that I have left the event as RIGHT click even though you specified LEFT click

    import wx
    
    class TextFrame(wx.Frame):
    
        def __init__(self):   
            wx.Frame.__init__(self, None, -1, 'Text Entry Example',   
                    size=(300, 250))   
            self.panel = wx.Panel(self, -1)   
            self.richLabel = wx.StaticText(self.panel, -1, "Rich Text")   
            self.richText = wx.TextCtrl(self.panel, -1,   
                    "If supported by the native control, this is reversed, and this is a different font.",   
                    size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2)   
            self.richText.Bind(wx.EVT_RIGHT_DOWN, self.OnTextCtrl1LeftDown) 
            self.richText.SetInsertionPoint(0) 
    
            #? how can I bind mouse event like leftdown on Text below 
            #? how can I bind mouse event like leftdown on Text below 
            self.richText.SetStyle(44, 52, wx.TextAttr("white", "black"))   
    
            points = self.richText.GetFont().GetPointSize()   
            f = wx.Font(points + 10, wx.ROMAN, wx.ITALIC, wx.BOLD, True)   
            self.richText.SetStyle(68, 82, wx.TextAttr("blue", wx.NullColour, f))   
    
            sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)   
            sizer.AddMany([self.richLabel, self.richText])   
            self.panel.SetSizer(sizer) 
    
    
        def OnTextCtrl1LeftDown(self,event): 
            m_pos = event.GetPosition()  # position tuple
            word_pos = self.richText.HitTest(m_pos)
            if word_pos[0] == 0:
                if word_pos[1] > 43 and word_pos[1] < 53:
                    print "You clicked on the word 'reserved'" 
                if word_pos[1] > 67 and word_pos[1] < 83:
                print "You clicked on the words 'Different Font'" 
    
    if __name__ == '__main__':
        test = wx.App()
        TextFrame().Show()
        test.MainLoop()