终端中的光标闪烁消除,如何?
Posted
技术标签:
【中文标题】终端中的光标闪烁消除,如何?【英文标题】:cursor blinking removal in terminal, how to? 【发布时间】:2012-06-11 21:00:59 【问题描述】:我使用以下行在我的 c++ 程序中输出模拟的进度信息,
double N=0;
double percent=0;
double total = 1000000;
for (int i; i<total; ++i)
percent = 100*i/total;
printf("\r[%6.4f%%]",percent);
效果很好!
但问题是我看到终端光标一直在数字中循环闪烁,这很烦人,有人知道如何摆脱这个吗?
我见过一些程序,例如 wget 或 ubuntu apt,它们也使用进度条或百分比,但它们似乎没有光标闪烁的问题,我想知道它们是如何做到的?
谢谢!
【问题讨论】:
【参考方案1】:您可以在DECSM
和DECRM
中使用DECTCEM
(DEC 文本光标启用模式)模式隐藏和显示光标:
fputs("\e[?25l", stdout); /* hide the cursor */
fputs("\e[?25h", stdout); /* show the cursor */
【讨论】:
你的意思是在循环中,在这个命令之后printf("\r[%6.4f%%]",percent);
?
无论在哪里需要。通常,您会在任何更新之前隐藏光标,执行所有更新,然后在最后再次显示它。如果您愿意,您甚至可以将它们全部合并到一个 printf
中。【参考方案2】:
只是猜测:尝试使用适当数量的“\b”(退格)字符而不是“\r”。
== 编辑 ==
我不是 Linux shell 向导,但这可能有用:
system("setterm -cursor off");
// ...display percentages...
system("setterm -cursor on");
别忘了#include <cstdlib>
或<iostream>
。
【讨论】:
为什么需要百分比?你可以一个接一个地写“#”字符。例如,每个新的 10%s 对应一个“#”。 哎呀,我喜欢数字 :) 好的,我会尝试 # 并让你知道结果,但无论如何,只是一个 google,有人说 wget 没有使用 ncurses 哎呀,好像关了就不能再开了 使用系统不好。 fork 之后执行的程序将执行此操作 ***.com/a/10995085/78712 。你这样可以吗?system("echo hello world!");
【参考方案3】:
避免光标闪烁的一种方法是(按照建议)暂时隐藏光标。
但是,这只是解决方案的一部分。您的程序也应该考虑到这一点:
隐藏光标并修改屏幕后,之前再次显示光标移动回到原来的位置。 隐藏/显示光标只会在您的更新只花费少量时间时使光标不会明显闪烁。如果您碰巧将此与一些耗时的过程混合在一起,您的光标会闪烁。使用setterm
的建议解决方案不可移植;它特定于 Linux 控制台。并且使用system
运行可执行文件并不是真正必要的。但即使是跑步
system("tput civis");
...
system("tput cnorm");
是对使用 setterm
的改进。
检查wget
的源代码没有发现任何隐藏光标的转义序列。您在进度条中看到的是,每当它执行一些耗时的操作时,它会将光标留在大致相同的位置。到终端的输出只需要很少的时间,以至于您不会注意到该行的瞬时重写(通过打印回车,然后重新写入大部分行)。如果速度较慢,那么隐藏光标会有所帮助——在一定程度上。
顺便说一句,这种光标隐藏技术在某些编辑器(vim 和 vile)的终端驱动程序中使用。
【讨论】:
我认为wget
没有这个问题的真正原因是因为它们打印到没有缓冲的stderr
,而不是缓冲的stdout
。【参考方案4】:
那些应用程序可能正在使用ncurses。见mvaddstr
【讨论】:
wget 和 fbi 是两个不使用 ncurses 但能够完全隐藏光标的程序示例。【参考方案5】:光标跳来跳去的原因是因为stdout
被缓冲了,所以你实际上不知道在某个时间点打印了多少个字符。 wget
没有跳跃光标的原因是它们实际上是打印到 stderr
而不是无缓冲的。请尝试以下操作:
fprintf(stderr, "\r[%6.4f%%]", percent);
如果您使用管道将其余输出保存在某处,这还有一个优点,即不会弄乱文件:
$ ./executable > log.data
【讨论】:
【参考方案6】:按插入键...如果不起作用,请按键盘上的 fn 键。 这肯定会工作 希望这会有所帮助
【讨论】:
以上是关于终端中的光标闪烁消除,如何?的主要内容,如果未能解决你的问题,请参考以下文章