是否有一种机制可以检测(突出显示并生成鼠标事件)wx.TextCtrl 中的文件或文件夹路径?
URL 检测存在类似的机制(使用 style = wx.TE_AUTO_URL 和 wx.TE_RICH)。
例子:
“这是我希望 TextCtrl 将C:\Temp\Folder\temp.txt检测为路径的示例。”
谢谢,奥马尔。
据我所知,没有内置样式可以满足您的需求。但是,您总是可以继承 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()