防止wxpython TextCtrl.WriteText()后出现换行
我有一个类似命令行的控制台,用于我的应用程序,每次输入命令后都会显示一个提示符“>>>”。问题是每次我让控制台显示“>>> ”时,它都会自动换行。用户虽然可以用退格键回到正确的行,但这样看起来实在太糟糕了。有没有办法解决这个问题?
1 个回答
我怀疑你在定义你的 TextCtrl
时用了 wx.TE_PROCESS_ENTER
这个样式,然后又绑定了 EVT_TEXT_ENTER
事件——我也是因为遇到同样的问题才这么想的。
我最开始的想法是写一个方法来处理 wx.EVT_TEXT_ENTER
,然后用 TextCtrl:Remove()
方法来删除内容。可惜这个方法似乎只能删除可见的字符。接着我想到了用 EmulateKeyPress()
方法配合退格键(WKX_BACK
)来删除换行符。这个方法可能可行,但我找不到一个好的办法来伪造 wx.KeyEvent
(不能直接用 event.m_keyCode
,因为 EVT_TEXT_ENTER
发送的是 CommandEvent
,而不是 KeyEvent
),所以我放弃了这个思路……呃,我是说这个解决方案留给读者自己去探索。
由于 wx.EVT_TEXT_ENTER
是一个 CommandEvent
,这让我找到了第三种有效的方法。与其绑定 wx.EVT_TEXT_ENTER
,我选择绑定 wx.EVT_CHAR
,并为 Return
键(ASCII 码 13)添加了特殊处理逻辑。然后我打算实现之前提到的 EmulateKeyPress()
,但当我把 wx.TE_PROCESS_ENTER
从 TextCtrl 的样式中去掉后,我发现换行符 \n
不再被偷偷添加了。代码如下:
import wx
class TestRun(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self, parent, title="StackO Test", size=(400,400))
self.control = wx.TextCtrl(self, id=wx.ID_ANY, style=wx.TE_MULTILINE)
self.control.Bind(wx.EVT_CHAR, self.OnPress)
self.Show(True)
def OnPress(self, event):
if event.GetKeyCode() == 13:
self.control.WriteText('\n>>>')
else:
event.Skip()
if __name__ == '__main__':
app = wx.App(False)
TestRun(None)
app.MainLoop()
event.Skip()
这一行非常重要;在我研究这个问题时,我了解到 KeyEvent
通常会跟着一个 CharEvent
。CharEvent
是将字符写入 TextCtrl
的部分。当你拦截 KeyEvent
时,CharEvent
只有在你明确调用的情况下才会被触发——所以如果你想让你的 TextCtrl
正常工作,event.skip()
是必不可少的。没有它,任何不是 ASCII 码 13 的键盘输入都不会有任何反应。
根据我的测试,似乎是因为定义 TextCtrl
使用了 wx.TE_PROCESS_ENTER
这个样式,导致每次调用 WriteText()
后都会自动添加一个换行符。我的方法可以绕过这个问题,不过你需要更多的工作来确保插入点始终在正确的位置等等。
祝你好运!