当textctrl改变时运行wxpython

时间:2011-08-16 20:26:46

标签: text wxpython highlighting

我在wxpython中创建一个简单的文本编辑器。我希望它能够编辑像python这样的代码,因此我想让它以与IDLE或Notepad ++类似的方式突出显示文本。我知道如何突出它,但我想要运行它的最好方法。我不知道是否可能,但我真正想要的是在按下按键时运行,而不是在循环检查是否按下它,以便节省处理。

import wx
class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(500,600))
        style = wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_RICH2
        self.status_area = wx.TextCtrl(self, -1,
                                   pos=(10, 270),style=style,
                                   size=(380,150))
        self.status_area.AppendText("Type in your wonderfull code here.")
        fg = wx.Colour(200,80,100)
        at = wx.TextAttr(fg)
        self.status_area.SetStyle(3, 5, at)
        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Setting up the menu.
        filemenu= wx.Menu()

        filemenu.Append(wx.ID_ABOUT, "&About","Use to edit python code")
        filemenu.AppendSeparator()
        filemenu.Append(wx.ID_EXIT,"&Exit"," Terminate the program")

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
        self.Show(True)


app = wx.App(False)
frame = MainWindow(None, "Python Coder")
app.MainLoop()

如果需要一个循环,那么最好的方法就是循环,使用while循环或

def Loop():
    <code>
    Loop()

添加了bind的新代码:

import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(500,600))
        style = wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_RICH2
        self.status_area = wx.TextCtrl(self, -1,
                                   pos=(10, 270),style=style,
                                   size=(380,150))
        #settup the syntax highlighting to run on a key press
        self.Bind(wx.EVT_CHAR, self.onKeyPress, self.status_area)
        self.status_area.AppendText("Type in your wonderfull code here.")
        fg = wx.Colour(200,80,100)
        at = wx.TextAttr(fg)
        self.status_area.SetStyle(3, 5, at)
        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Setting up the menu.
        filemenu= wx.Menu()

        filemenu.Append(wx.ID_ABOUT, "&About","Use to edit python code")
        filemenu.AppendSeparator()
        filemenu.Append(wx.ID_EXIT,"&Exit"," Terminate the program")

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
        self.Show(True)


    def onKeyPress (self, event):
        print "KEY PRESSED"
        kc = event.GetKeyCode()
        if kc == WXK_SPACE or kc == WXK_RETURN:
            Line = self.status_area.GetValue()
            print Line
app = wx.App(False)
frame = MainWindow(None, "Python Coder")
app.MainLoop()

2 个答案:

答案 0 :(得分:1)

在您的MainWindow __init__功能中添加此

self.Bind(wx.EVT_CHAR, self.onKeyPress, self.status_area)

然后在MainWindow中定义onKeyPress

def onKeyPress (self, event):
    kc = event.GetKeyCode()
    if kc == WXK_SPACE or kc == WXK_RETURN:
        #Run your highlighting code here

想一想,这可能不是进行代码突出显示的最有效方式。让我看看这个。但与此同时你可以试试这个。

编辑: 看看这个 - StyledTextCtrl。我认为它更符合你的需要。

答案 1 :(得分:0)

当我遇到同样的问题时,我通过创建自定义事件解决了这个问题。

首先,我创建了一个 TextCtrl 的子类,所以我在代码中有一个地方可以从以下位置引发/发布自定义事件:

import  wx.lib.newevent
(OnChangeEvent, EVT_VALUE_CHANGED) = wx.lib.newevent.NewEvent()

class TextBox(wx.TextCtrl):
    old_value = u''

    def __init__(self,*args,**kwargs):
        wx.TextCtrl.__init__(self,*args,**kwargs)
        self.Bind(wx.EVT_SET_FOCUS, self.gotFocus) # used to set old value
        self.Bind(wx.EVT_KILL_FOCUS, self.lostFocus) # used to get new value

    def gotFocus(self, evt):
        evt.Skip()
        self.old_value = self.GetValue()

def lostFocus(self, evt):
    evt.Skip()
    if self.GetValue() != self.old_value:
        evt = OnChangeEvent(oldValue=self.old_value, newValue=self.GetValue())
        wx.PostEvent(self, evt)

现在,在我的框架代码中,这是我绑定事件并使用它的片段。

summ_text_ctrl = TextBox(self, -1, size=(400, -1))
summ_text_ctrl.Bind(EVT_VALUE_CHANGED, self.onTextChanged)

def OnTextChanged(self, evt):
    evt.Skip()
    print('old Value: %s' % evt.oldValue )
    print('new Value: %s' % evt.newValue )