开发者

output readonly, input editable with wx.textctrl?

开发者 https://www.devze.com 2023-02-06 06:17 出处:网络
HI, guys, I am using wxpython to develop a GUI for software configuration, launching and interaction. I want something like a CLI shell window (like pycrust) embedded inside the GUI to interact with

HI, guys,

I am using wxpython to develop a GUI for software configuration, launching and interaction. I want something like a CLI shell window (like pycrust) embedded inside the GUI to interact with a long-term running background process. I could give the input via this shell window and print the output on this window. My current code works very well. But there is problem of editing style, because wx.TextCtrl is simply an editable text window. e.g., I could overwrite or remove any previous text characters or type new input at any location. This is not desirable.

How can I make the wx.TextCtrl like a shell window, i.e. make the output readonly, while keep input editable? e.g.,

1) when input new command, the position only starts after prompt.

2) The user cannot change or replace any previous output text. I want to force certain restriction, for interaction purpose.

Is there a way to fix the curse prompt? If so, then 开发者_StackOverflow中文版my problem will be solved, because the user will have no chance to move the curse.

Or is there a way to set certain part of the text (the output and the prompt) readonly?

Or another solution, thanks to 9000's answer, is that I make a grid of windows (a StaticTextCtrl or readonly TextCtrl for output in the upper window; prompt ">>>" on the bottom left area; invisible-border editable window or entry dialog on the bottom right area for input).

any suggestions? Is there any better choice? Thanks a lot!


You could consider using some kind of input buffer.

Capture each wx.EVT_KEY_DOWN event from the TextCtrl. If it's a keystroke that produces a character, append it to your buffer and let it go through. If it's a backspace, remove the last character from the buffer and allow it, or if there are no characters left in the buffer, don't allow it. This will protect your command prompt on the current line.

You would also have to address each keyboard or mouse event that could reposition the cursor. If you don't want the user to be able to move the cursor around within the current line or move to previous lines, you'll have to detect and cancel arrow keys, home, end, page up, page down, mouse clicks, etc. It could be tough to lock down completely.

Example for preventing keystrokes:

    # inside your Frame init function...
    self.text = wx.TextCtrl(self.panel, wx.ID_ANY, style=wx.TE_MULTILINE)
    self.text.Bind(wx.EVT_KEY_DOWN, self.OnKey)
    # ...

def OnKey(self, evt):
    # keycodes for arrow keys, page up/down
    KEYS_TO_CANCEL = [314, 315, 316, 317, 366, 367]

    keycode = evt.GetKeyCode()

    if keycode in KEYS_TO_CANCEL:
        print('Cancelled!')
    else:
        evt.Skip()

Good luck!


In our product we have a console made up of two edit windows, separated by a thin line. The upper window is the output window, it is read-only. The lower window is editable. Once you have written a command in it and submitted it, the command is removed from the lower window and goes to the upper window, along with command's output.

You can click the upper window, select something from it, scroll it up, etc, all without removing the command you're currently editing from sight. Then you click on the lower window or press any key, and the control returns to the lower window, where you continue to craft your next command.


Just keep track of the location of the prompt each time you display it. Intercept all keypresses and releases, and if anything causes text before the prompt to change, veto that event. It's not that hard, it just takes a little attention to detail and some diligence to capture all text-modification events.

0

精彩评论

暂无评论...
验证码 换一张
取 消