当textctrl改变时wxpython运行

发布于 2024-11-30 01:54:28 字数 3080 浏览 1 评论 0原文

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

I am making a simple text editor in wxpython. I would like it to be able to edit code such as python, and as such I would like to have it highlight the text in a similar manner to IDLE or Notepad++. I know how I would highlight it, but I would like the best way of running it. I don't know if it is possible but what I would really like is to run whenever a key is pressed, and not on a loop checking if it is pressed, so as to save on processing.

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

If a loop is needed what would be the best way to make it loop, with a while loop, or a

def Loop():
    <code>
    Loop()

My new code with the added 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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

誰ツ都不明白 2024-12-07 01:54:28

在您的 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 。我认为它更符合您的需求。

In your MainWindow __init__ function add this

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

then define onKeyPress in MainWindow

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

Come to think of it, this might not be the most efficient way of doing code highlighting. Let me look this up. But in the meantime you can try this.

Edit:
Take a look at this - StyledTextCtrl . I think its more along the lines of what you need.

短暂陪伴 2024-12-07 01:54:28

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

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

I solved this when I faced the same issue by creating a custom event.

First, I created a subclass of the TextCtrl, so I had a place in code to raise/post the custom event from:

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)

Now, in my frame's code, here is a snippet of me Binding the event, and using it.

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 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文