【问题标题】:wxpython run when textctrl changeswxpython 在 textctrl 更改时运行
【发布时间】:2011-10-28 09:53:23
【问题描述】:

我正在用 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()

我添加了绑定的新代码:

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()

【问题讨论】:

  • 当一个键被按下时你想运行什么?突出显示?
  • 我希望它突出显示字符串中的关键字,以便突出显示 python 代码。所以“如果”将是紫色文本,并且不同的功能也会被着色。如果输入了一个单词,我知道如何使我的代码突出显示文本。如果 textctrl 中的文本发生更改,我希望它通过一段代码运行。因此,如果我在窗口的文本框中输入“我喜欢苹果”并将其更改为“我喜欢苹果派”,由于“派”中的每次按键,它都会运行代码块 4 次。跨度>
  • 嗯,减少这种情况的一种方法可能是仅在按下空格键或回车键时运行突出显示代码。因为这表明一个单词或一行是完整的。
  • 听起来不错,但是在输入 textctrl 时如何判断是否按下了空格键或回车键。
  • 您当前没有在文本控件中按下键时运行高亮代码吗?只需检查事件的关键代码。如果是空格或回车对应的键码,则运行你的highlighing,否则通过。

标签: text wxpython highlighting


【解决方案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 。我认为它更符合您的需求。

【讨论】:

  • 我尝试了你给我的,但是当我调试它时,我无法让它做任何事情。
  • 我知道如何为文本着色,我只需要在按下键盘上的一个键时运行它,这就是你的代码的样子,但我把“打印”测试“”放在哪里你在这里有#Run你的突出显示代码,当我打字时它从未打印出来。对于我正在做的事情,styledTextCtrl 看起来太复杂了。
  • 把调试放在onKeyPress中。 print "at the start" 然后print "value of keycode %d" % kc 获得密钥后
  • 我这样做了,它也不打印任何东西或给我任何运行的指示。
  • 将新代码粘贴到您的问题中。并粘贴所有内容。用按键和一切。
【解决方案2】:

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

首先,我创建了 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)

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

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 )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-28
    • 2011-08-16
    • 1970-01-01
    • 2015-11-01
    • 2011-07-12
    • 2023-03-11
    • 2012-12-27
    • 2013-09-14
    相关资源
    最近更新 更多