0

是否有一种机制可以检测(突出显示并生成鼠标事件)wx.TextCtrl 中的文件或文件夹路径?

URL 检测存在类似的机制(使用 style = wx.TE_AUTO_URL 和 wx.TE_RICH)。

例子:

“这是我希望 TextCtrl 将C:\Temp\Folder\temp.txt检测为路径的示例。”

谢谢,奥马尔。

4

1 回答 1

0

据我所知,没有内置样式可以满足您的需求。但是,您总是可以继承 wx.TextCtrl。

下面提供的自定义小部件更改匹配正则表达式的字符串小节的样式。当光标悬停在这些子字符串之一上时,将生成自定义命令事件“EVT_TXT_PATH”。

正则表达式可能需要根据您希望控件识别的路径进行调整。我从可能对您有用的正则表达式库中获取了一个:

http://regexlib.com/REDetails.aspx?regexp_id=127

import wx
import wx.lib.newevent

import re

re_path = re.compile(r'([A-Z]:\\[^/:\*\?<>\|]+\.\w{2,6})|(\\{2}[^/:\*\?<>\|]+\.\w{2,6})')

TextPathEvent, EVT_TXT_PATH = wx.lib.newevent.NewCommandEvent()

class PathTextCtrl(wx.TextCtrl):

    def __init__(self, parent, id=wx.ID_ANY, value="",
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
                 style=0, validator=wx.DefaultValidator,
                 name=""):

        style = style | wx.TE_RICH

        super(PathTextCtrl, self).__init__(parent, id, value, pos, size,
                                           style,validator, name)

        self.groups = []

        self.SetDefaultStyle(wx.TextAttr(wx.BLACK, wx.NullColor))

        self.Bind(wx.EVT_TEXT, self.OnText, self)
        self.Bind(wx.EVT_MOTION, self.OnMotion, self)

    def OnText(self, evt):

        self.StyleText()

        evt.Skip()

    def StyleText(self):

        self.groups = []

        string = self.GetValue()
        n = len(string)

        defstyle = self.GetDefaultStyle()
        self.SetStyle(0, n, defstyle)

        font = self.GetFont()
        font.SetUnderlined(True)
        style = wx.TextAttr(colText=wx.BLUE, font=font)       

        index = 0

        while True:

            match = re_path.search(string, index, n)

            if match:

                start, end = match.span()

                self.groups.append((start, end))

                self.SetStyle(start, end, style)

                index = end+1

            else: return

    def OnMotion(self, evt):

        pos = evt.GetPosition()

        result = self.HitTestPos(pos)

        for group in self.groups:

            x, y = group

            if x <= result[1] <= y:

                string = self.GetValue()[x:y]

                print string

                event = TextPathEvent(id=self.GetId(), url=string)

                wx.PostEvent(self, event)

        evt.Skip()

class TestFrame(wx.Frame):

    def __init__(self, parent, id=wx.ID_ANY, title=""):

        super(TestFrame, self).__init__(parent, id, title)

        panel = wx.Panel(self)

        text = PathTextCtrl(panel, size=(400, -1))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(text, 0, wx.ALL, 10)
        panel.SetSizer(sizer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel)
        self.SetSizer(sizer)

        self.Fit()

if __name__ == '__main__':

    app = wx.App(redirect=True)
    top = TestFrame(None, title="PathTextCtrl Demonstration")
    top.Show()
    app.MainLoop()
于 2012-04-29T17:24:00.183 回答