2

我刚刚做了一个小聊天 CLI 应用程序,它实际上工作得很好!

不幸的是,当一个人输入一条消息并同时接收其他人的消息时,两者都是交错的......这会变得非常糟糕:

elton: Hey!
john: how are you doing?
fine anjohn: still not to bed?!
d john: haha
you?elton: fine and you?

我正在寻找一种方法来避免这种问题。例如“保留”最后一行供用户输入或在接收到数据时处理一些动作以重新计算用户输入的位置。

经过一番研究,我发现我将使用 getch() 逐个检索每个字符。这样我就可以定期检查是否有新消息正在等待显示并处理这种情况。

但是如果我使用 getch() 我必须手动重新定义基本操作(例如退格、左右移动......),一些字符占用超过一个字节。简而言之,它无法使用。

4

2 回答 2

1

做这种事情的常用方法是编写“控制台模式 GUI”而不是纯 CLI。

例如,您可以非常轻松地创建一个非常简单的界面,其中包含一个ROWS-2xCOLS输出窗口、一个1xCOLS分隔线或模式行以及一个1xCOLS输入窗口——如 IRC 客户端、emacs 等中所见。例如:

或者你可以做一个拆分视图,其中一个ROWS/2xCOLS窗口用于其他人/人的聊天,而在该窗口下方的ROWS/2xCOLS窗口用于用户当前和以前的消息,如大多数早期 Unix 聊天程序中所见。

或者像一些现代 IRC 客户端所做的那样,随处可见的窗口会在适当的时候弹出和消失。

Python 具有curses内置支持,但在 Windows 上不支持。如果你想要一个跨平台的解决方案,或者一个仅限 Windows 的解决方案,请参阅python 中跨平台控制台应用程序中的 curses-like library,答案可能就在那里。

这是来自 IRC 客户端 BitchX 的屏幕截图,让您了解无需太多工作即可实现的功能: 婊子X

于 2013-01-16T21:13:43.450 回答
1

据我所知,您在这里有几个选择。通常只需调用 getch,您就可以在所谓的“熟”模式下运行终端。这意味着终端只是按照字符到达的顺序显示字符,没什么特别的。但是,正如您所发现的那样,您会遇到竞争条件。

选项 1:您一次读取一个字符,缓冲整行。当新行到达并且您想将其打印出来时,您必须(a)抓住某种打印互斥锁(程序内部),(b)清除当前行(print '\r[ space][space][space]...\r'),(c) 打印输入行 + '\n',以及 (d) 将先前的缓冲区恢复到屏幕(通过打印)并解锁互斥锁。

这变得丑陋。快速地。正如您所发现的,没有行编辑支持或任何花哨的东西。这种方法唯一的好处是它可能适用于大约 99% 的终端。

选项 2:您将终端置于原始模式。在这种模式下,您可以完全控制终端,但是您会失去非常基本的功能(例如,除非您手动输出,否则键入一个键不会显示它)。您仍然需要手动实现导航等功能,但至少它会起作用。这种方法可能是最灵活的,给你最大的控制权,但是这样工作非常困难,这就是他们发明的原因......

选项 3:您使用 ncurses(或类似的终端库)。这些概念有点难,但比在纯原始模式下做事要容易得多。编辑和窗口化(或者如您所说,保留一行)是内置的。该界面可能比您从熟模式中获得的更漂亮。

编辑我在这里谈论了很多关于 *nix 终端的内容,其中大部分不适用于 Windows。

于 2013-01-16T21:19:36.420 回答