移动控制台光标

时间:2022-04-30 21:03:36

I'm currently designing a CLI interface for linux, and for various reasons I am not able to use ncurses. I am using exclusively C++ and the Qt framework.

我目前正在为linux设计一个CLI接口,由于各种原因,我不能使用ncurses。我只使用c++和Qt框架。

Therefore, in order to have a user-friendly interface, I have to run this getch loop in a separate thread:

因此,为了有一个用户友好的界面,我必须在一个单独的线程中运行这个getch循环:

https://*.com/a/912796/3605689

https://*.com/a/912796/3605689

Which basically means I have to implement all basic functionalities (such as backspace) by myself. I have already implemented command completion and command history(like when you press tab or uparrow/downarrow in linux), but I can't figure out how to implement leftarrow/rightarrow (aka seeking through the typeahead).

这基本上意味着我必须自己实现所有的基本功能(比如backspace)。我已经实现了命令完成和命令历史(比如在linux中按tab或uparrow/downarrow),但是我不知道如何实现leftarrow/右翼tarrow(也就是通过typeahead查找)。

Normally, I implement it like this: upon every gech which is not equal to -1, I check whether the user has pressed a special key (one that modifies the typeahead somehow). I then clear the stdout using the following function:

通常,我是这样实现的:在每个不等于-1的gech上,我检查用户是否按了一个特殊的键(一个以某种方式修改了typeahead的键)。然后使用以下函数清除stdout:

void inputobject::clear_line(int nletters)
{
    QTextStream(stdout) << "\033[2K";

    for(int i = 0; i < nletters;i++){
        QTextStream(stdout) << "\b";
    }

    rewind(stdout);
}

And replace it with something else, effectively simulating the typeahead. For example, in the case of backspace, I would save the command call clear_line, and print the command out again, just with one less letter, behaving exactly as a normal console application would.

用别的东西代替它,有效地模拟前面的字体。例如,在backspace的情况下,我将保存命令调用clear_line,并再次打印命令,只需要少一个字母,其行为与正常的控制台应用程序完全相同。

My real problem is with the cursor, in the case of left/rightarrow, I need to move the cursor visual in order to be able to indicate where in the text is the user seeking:移动控制台光标

我真正的问题是光标,在左/右tarrow的情况下,我需要移动光标的视觉效果,以便能够指示用户在文本中寻找的位置:

Because of the nature of how I rewrite the given stdout line to simulate the typeahead, it does not really matter where the cursor REALLY is, as long as it stays on the same line - it is just the visual that matters. How can I achieve moving the cursor visual on linux?

由于我如何重写给定的stdout行来模拟typeahead,所以只要游标保持在同一条线上,那么游标在哪里并不重要——重要的只是视觉效果。如何在linux上实现光标移动?

2 个解决方案

#1


3  

The answer was provided in the comment by Evilruff:

这个问题的答案是由Evilruff提供的:

Cursor Movement

光标移动

ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:

ANSI转义序列允许你在屏幕上随意移动光标。这对于shell脚本生成的全屏用户界面更有用,但也可以在提示符中使用。运动转义序列如下:

  • Position the Cursor: \033[;H Or \033[L;Cf puts the cursor at line L and column C.
  • 定位光标:\033[;H或\033[L;Cf将光标置于L和C列。
  • Move the cursor up N lines: \033[NA
  • 将光标向上移动N行:\033[NA]
  • Move the cursor down N lines: \033[NB
  • 将光标向下移动N行:\033[NB]
  • Move the cursor forward N columns: \033[NC
  • 将光标向前移动N列:\033[NC]
  • Move the cursor backward N columns: \033[ND

    将光标向后移动N列:\033[ND]

  • Clear the screen, move to (0,0): \033[2J

    清除屏幕,移动到(0,0):\033[2J]

  • Erase to end of line: \033[K

    擦到行尾:\033[K]

  • Save cursor position: \033[s

    拯救光标位置:033 \[s

  • Restore cursor position: \033[u
  • 033年恢复光标位置:\[u

#2


0  

Not using ncurses and co is a serious limitation.

不使用ncurses和co是一个严重的限制。

It is hell to make correct input/output on shell for displaying anything.

为了显示任何东西,在shell上进行正确的输入/输出是地狱。

The only others real solutions (I can't think as a solution to reimplement a ncurse-like library) I think of are:

我唯一想到的其他真正的解决方案(我无法将其视为重新实现类似ncurse的库的解决方案)是:

  • making call to dialog (for some example www.linuxjournal.com/article/2807 and for the doc: http://linux.die.net/man/1/dialog)
  • 调用dialog(例如www.linuxjournal.com/article/2807和doc: http://linux.die.net/man/1/dialog)
  • using the framebuffer mecanism with Qt4 (here)
  • 在Qt4中使用framebuffer mecanism(这里)

#1


3  

The answer was provided in the comment by Evilruff:

这个问题的答案是由Evilruff提供的:

Cursor Movement

光标移动

ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:

ANSI转义序列允许你在屏幕上随意移动光标。这对于shell脚本生成的全屏用户界面更有用,但也可以在提示符中使用。运动转义序列如下:

  • Position the Cursor: \033[;H Or \033[L;Cf puts the cursor at line L and column C.
  • 定位光标:\033[;H或\033[L;Cf将光标置于L和C列。
  • Move the cursor up N lines: \033[NA
  • 将光标向上移动N行:\033[NA]
  • Move the cursor down N lines: \033[NB
  • 将光标向下移动N行:\033[NB]
  • Move the cursor forward N columns: \033[NC
  • 将光标向前移动N列:\033[NC]
  • Move the cursor backward N columns: \033[ND

    将光标向后移动N列:\033[ND]

  • Clear the screen, move to (0,0): \033[2J

    清除屏幕,移动到(0,0):\033[2J]

  • Erase to end of line: \033[K

    擦到行尾:\033[K]

  • Save cursor position: \033[s

    拯救光标位置:033 \[s

  • Restore cursor position: \033[u
  • 033年恢复光标位置:\[u

#2


0  

Not using ncurses and co is a serious limitation.

不使用ncurses和co是一个严重的限制。

It is hell to make correct input/output on shell for displaying anything.

为了显示任何东西,在shell上进行正确的输入/输出是地狱。

The only others real solutions (I can't think as a solution to reimplement a ncurse-like library) I think of are:

我唯一想到的其他真正的解决方案(我无法将其视为重新实现类似ncurse的库的解决方案)是:

  • making call to dialog (for some example www.linuxjournal.com/article/2807 and for the doc: http://linux.die.net/man/1/dialog)
  • 调用dialog(例如www.linuxjournal.com/article/2807和doc: http://linux.die.net/man/1/dialog)
  • using the framebuffer mecanism with Qt4 (here)
  • 在Qt4中使用framebuffer mecanism(这里)