是否有一种机制可以检测(突出显示并生成鼠标事件)wx.TextCtrl中的文件或文件夹路径?
URL检测存在类似的机制(使用style = wx.TE_AUTO_URL和wx.TE_RICH)。
示例:
“这是一个示例,我希望TextCtrl将 C:\ Temp \ Folder \ temp.txt 检测为路径。”
谢谢,Omer。
答案 0 :(得分: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()