【问题标题】:How do I make a find dialog in StyledTextCtrl?如何在 StyledTextCtrl 中创建查找对话框?
【发布时间】:2018-08-16 15:07:09
【问题描述】:

有一个关于这个主题的现有问题:Find text dialog with wxpython,但它在 TextCtrl 中。于是我把TextCtrl改成了StyledTextCtrl,并测试了一下。但是我收到了这个错误:

in wxStyledTextCtrl::SetStyle(): not implemented

如何使 SetStyle 成为一个选择,以便您可以点击离开?这是我的代码:

import wx
import wx.stc as stc

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.tc = stc.StyledTextCtrl(self, style=wx.TE_MULTILINE | wx.TE_WORDWRAP)
        self.bt_find = wx.Button(self, -1, "find")

        self.Bind(wx.EVT_BUTTON, self.on_button, self.bt_find)
        self.Bind(wx.EVT_FIND, self.on_find)

        self.pos = 0
        self.size = 0
        #
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tc, 1, wx.EXPAND, 0)
        sizer.Add(self.bt_find, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()

    def on_button(self, event):
        self.txt = self.tc.GetValue()
        self.data = wx.FindReplaceData()   # initializes and holds search parameters
        self.dlg = wx.FindReplaceDialog(self.tc, self.data, 'Find')
        self.dlg.Show()

    def on_find(self, event):
        fstring = self.data.GetFindString()          # also from event.GetFindString()
        self.pos = self.txt.find(fstring, self.pos)
        self.size = len(fstring)
        self.tc.SetStyle(self.pos, self.pos+self.size, wx.TextAttr("red", "black"))


if __name__ == "__main__":

    app = wx.PySimpleApp(0)
    frame_1 = MyFrame(None, wx.ID_ANY, "")
    frame_1.Show()
    app.MainLoop()

【问题讨论】:

标签: python wxpython


【解决方案1】:

StyledTextCtrl 看起来像一个高度复杂的野兽,我只能假设您必须彻底阅读scintilla 文档http://www.scintilla.org/
我评论中的链接指向使用SetStyling 函数而不是AddSelection
这就是我使用它管理的:

import wx
import wx.stc as stc

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.tc = stc.StyledTextCtrl(self, style=wx.TE_MULTILINE | wx.TE_WORDWRAP)
        self.bt_find = wx.Button(self, -1, "find")

        self.Bind(wx.EVT_BUTTON, self.on_button, self.bt_find)
        self.Bind(wx.EVT_FIND, self.on_find)

        self.pos = 0
        self.size = 0
        #
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tc, 1, wx.EXPAND, 0)
        sizer.Add(self.bt_find, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()

    def on_button(self, event):
        self.txt = self.tc.GetValue()
        self.data = wx.FindReplaceData()   # initializes and holds search parameters
        dlg = wx.FindReplaceDialog(self.tc, self.data, 'Find')
        dlg.Show()

    def on_find(self, event):
        self.tc.StartStyling(pos=0, mask=0xFF)
        self.tc.SetStyling(length=len(self.txt), style=0)
        fstring = event.GetFindString()
        self.size = len(fstring)
        while True:
            self.pos = self.txt.find(fstring, self.pos)
            if self.pos < 0:
                break
            self.tc.StyleSetSpec(1, "fore:#FF0000,back:#000000")
            self.tc.StartStyling(pos=self.pos, mask=0xFF)
            self.tc.SetStyling(length=self.size, style=1)
            self.pos += 1
        self.pos = 0

if __name__ == "__main__":

    app = wx.App()
    frame_1 = MyFrame(None, wx.ID_ANY, "")
    frame_1.Show()
    app.MainLoop()

【讨论】:

  • 感谢您的帮助,您是传奇
  • 还有一个问题,我怎么做才能让你点击的时候去掉Styling?
  • 那将是一个不同的问题。不过,答案在上面。 on_find 的前两行清除了以前的样式,因此预先将 self.tc 绑定到 EVT_LEFT_DOWN 并使用这两行
  • self.tc.Bind(wx.EVT_LEFT_DOWN, self.remove_find) 可能会提高您的胜算。
猜你喜欢
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
相关资源
最近更新 更多