程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(5)

使用wxStyledTextCtrl实现代码提示

发布于2019-08-06 10:44     阅读(877)     评论(0)     点赞(5)     收藏(4)


       wxStyledTextCtrl是wxPython对流行的Scintilla的包装,Scintilla的网站(http://www.scintilla.org/),

wxStyledTextCtrl的文档位置(https://docs.wxpython.org/wx.stc.StyledTextCtrl.html#wx.stc.StyledTextCtrl),不过不要期望太高,这些文档最多算聊胜于无。(看来国外的程序员也不爱写文档,天下乌鸦一般黑:))。

       wxStyledTextCtrl是一个功能强大的富文本编辑控件,常见的编辑器功能都能找到,包括代码高亮,搜索替换,拷贝粘贴,回退等,后续我将逐步提供说明和例子代码,以供大家参考。今天先说代码提示。

创建Frame

首先创建Frame,这个Frame由工具条和wxStyledTextCtrl组成。

    class myFrame(wx.Frame):

        def __init__(self,parent,title):
        wx.Frame.__init__(self,parent,title=title,size=(800,600))

        #创建工具条
        tb=wx.Frame.CreateToolBar(self,style=wx.TB_FLAT|wx.TB_HORIZONTAL)
        tb.AddTool(201,u"回退",wx.Bitmap("./icos/undo.bmp"))
        tb.AddTool(202,u"重做",wx.Bitmap("icos/redo.bmp"))
        tb.AddSeparator()
        tb.AddTool(101,u"拷贝",wx.Bitmap("icos/copy.bmp"))
        tb.AddTool(102,u"粘贴",wx.Bitmap("icos/paste.bmp"))
        tb.AddTool(103,u"剪贴",wx.Bitmap("icos/cut.bmp"))
        tb.AddTool(104,u"搜索",wx.Bitmap("icos/search.bmp"))
        tb.Realize()
        
        #在工具条下方创建StyledTextCtrl编辑控件
        self.control=stc.StyledTextCtrl(self,style=0)
        
        #创建一个用于代码提示的AutoComplete对象
        self._autocomplete=AutoComplete()

        #绑定工具条事件和处理函数
        tb.Bind(wx.EVT_TOOL,self.OnToolSelected)
        
        #绑定按键事件
        self.control.Bind(wx.EVT_KEY_DOWN,self.OnKeyPressed)
        self.control.Bind(wx.EVT_CHAR,self.OnChar)


        self.Show(True)

         因为代码提示是在键入的过程中发生的,所以需要跟踪键盘事件,所以把按键事件与处理函数做了绑定。

  AutoComplete类

在代码提示过程中需要动态根据用户输入提供建议,所以创建了一个_autocomplete对象,它的类代码:

class AutoComplete:
    def __init__(self):
        self.suggests=keyword.kwlist
        self.prefix=""
        self.key=""
    def append(self,char):
        self.prefix+=char
    def back(self):
        if len(self.prefix)>1:
            self.prefix=self.prefix[:-1]
        else:
            self.prefix=""
    def clear(self):
        self.prefix=""
    @property
    def length(self):
        return len(self.prefix)

    def getsugs(self):
        return [word for word in self.suggests if word.startswith(self.prefix)]

        这个类维护一个用户当前已输入的字符串,用户每输入一个字符都附加在字符串后面,每次输入退格键,字符串删掉最后的字符。getsugs()函数根据字符串在关键字列表中查找匹配的候选关键字,并返回一个推荐列表。

跟踪键盘事件

    def OnKeyPressed(self,evt):
        key=evt.GetKeyCode()
        control=evt.ControlDown()
        alt=evt.AltDown()
        shift=evt.ShiftDown()
        if key in self.AutoCompStopwords and not control and not alt and not shift:
            if self.control.AutoCompActive():
                self.control.AutoCompComplete()
            self._autocomplete.clear()
        elif key==wx.WXK_BACK and not control and not alt and not shift:
            self._autocomplete.back()
            self.code_complete()
        evt.Skip()

    def OnChar(self,evt):
        control = evt.ControlDown()
        alt = evt.AltDown()
        shift = evt.ShiftDown()
        try:
            char = chr(evt.GetUnicodeKey())
            if char.isprintable() and char!=" ":
                self._autocomplete.append(char)
        except ValueError:
            #self._autocomplete.clear()
            if self.control.AutoCompActive():
                self.control.AutoCompCancel()
        if not control and not alt and not shift:
            self.code_complete()
        evt.Skip()

我们提供了两个跟踪键盘事件的函数,它们之间还是有些区别的。主要目的是区分可打印字符与功能键。AutoCompStopwords就是指定遇到什么样的按键代码提示结束,常见的包括回车、空格、分号、点号等。代码提示结束有两种情况,一种是用户在列表中选择其中一项,填入到编辑器中,另一种是用户输入的内容匹配不到任何关键字。

每个处理函数后面都加上了evt.Skip()目的是不要打破系统的消息处理机制,使得系统有时间处理必要的消息。有点像以前VB时代的DoEvents。

在遇到AutoCompStopwords后,需要把_autocomplete中的字符串清空,等待下一个词的编辑。这两个事件处理代码中都调用了code_complete()函数,其代码:

    def code_complete(self):
        choices=self._autocomplete.getsugs()
        if choices and self._autocomplete.length>=1:
            choices.sort()
            self.control.AutoCompShow(self._autocomplete.length-1," ".join(choices))
        else:
            if self.control.AutoCompActive():
                self.control.AutoCompCancel()

就是获取推荐列表,并显示在编辑器中。AutoCompShow(nlength,suggents),其中第一个参数nlength是指匹配多少个字符开始显示,suggents是一个分隔符隔开的推荐列表字符串,分隔符可以设置,不过一般保持缺省就可以了,缺省是空格。

建立主程序

建立一个主程序的入口,并建立消息循环机制。这些都是wxPython的规定动作。

if __name__=="__main__":
    app=wx.App(False)
    frame=myFrame(None,'Simple Editor')
    app.MainLoop()


 

 



所属网站分类: 技术文章 > 博客

作者:丑八怪

链接:https://www.pythonheidong.com/blog/article/7840/9abb62514566eff248bb/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

5 0
收藏该文
已收藏

评论内容:(最多支持255个字符)