如何将光标向上移动2行到开头?

huangapple go评论94阅读模式
英文:

How do I move the cursor 2 lines up to the beginning?

问题

如何将光标上移 2 行并返回到开头?

我有一个应用程序,它将一些数据输出到控制台,然后启动一个定时器来更新数据。整个输出看起来像这样:

重要数据 1
重要数据 2
重要数据 3
01 分钟 51 秒后的下一个更新数据...
要停止程序,请按 Ctrl+E

但是当定时器的大小变小时,该行没有完全擦除:

> 55 秒后的下一个更新数据...秒...

它应该是:

> 55 秒后的下一个更新数据...

我知道为什么会发生这种情况,并且我有一个避免这种效果的想法,我只需在输出行之前用空格填充它。我想要输出空行以擦除旧数据并输出更新的计时器。

clear_line_timer = ''.join(" " for i in range(len_line_timer))
clear_line_info = ''.join(" " for i in range(len_line_info))
line_timer = 'Next update data after ' + timerToString(seconds) + ' ...'
line_info = 'To stop the program, press Ctrl+E'
len_line_timer = len(line_timer)
len_line_info = len(line_info)

理论上,这应该可以工作,**但我不知道如何将光标指针返回到计时器行的开头。如何在输出之前将光标返回到计时器行的开头?**我希望它的工作方式与Windows和Linux/Unix类似。

用于回放的完整代码

import time

len_line_timer = 0
len_line_info = 0


def timerToString(seconds: int) -> str:
    if seconds is not None:
        seconds = int(seconds)
        d = seconds // (3600 * 24)
        h = seconds // 3600 % 24
        m = seconds % 3600 // 60
        s = seconds % 3600 % 60
        if d > 0:
            return '{:02d}d {:02d}h {:02d}m {:02d}s'.format(d, h, m, s)
        elif h > 0:
            return '{:02d}h {:02d}m {:02d}s'.format(h, m, s)
        elif m > 0:
            return '{:02d} minutes {:02d} seconds'.format(m, s)
        elif s > 0:
            return '{:02d} seconds'.format(s)
    return 'now';


def timer(seconds):
    global len_line_timer
    global len_line_info

    clear_line_timer = ''.join(" " for i in range(len_line_timer))
    clear_line_info = ''.join(" " for i in range(len_line_info))
    line_timer = 'Next update data after ' + timerToString(seconds) + ' ...'
    line_info = 'To stop the program, press Ctrl+E'
    len_line_timer = len(line_timer)
    len_line_info = len(line_info)
    ####################################################################################
    # 你需要以某种方式将光标指针返回到计时器行的开头 #
    ####################################################################################
    print(clear_line_timer + '\r', end='')
    print(line_timer + '\r', end='')
    print(clear_line_info + '\r', end='')
    print(line_info + '\r', end='')


if __name__ == '__main__':
    print("重要数据 1")
    print("重要数据 2")
    back_timer = 70
    counter = back_timer
    while True:

        timer(counter)

        counter -= 1
        time.sleep(1)
        if counter <= 0:
            counter = back_timer
英文:

How do I move the cursor 2 lines up to the beginning?

I have an application that outputs some data to the console, after which it turns on a timer to update the data. The whole output looks like this

Important data 1
Important data 2
Important data 3
Next update data after 01 minutes 51 seconds ...
To stop the program, press Ctrel+E 

But there is a problem when the timer size becomes smaller, the line is not completely erased

> Next update data after 55 seconds ...seconds ...

And it should be

> Next update data after 55 seconds ...

I know why this is happening, and I had an idea to avoid such an effect, I'll just fill it with spaces before outputting a line.
I want to output empty lines to erase the old data and output an updated timer

clear_line_timer = &#39;&#39;.join(&quot; &quot; for i in range(len_line_timer))
clear_line_info = &#39;&#39;.join(&quot; &quot; for i in range(len_line_info))
line_timer = &#39;Next update data after &#39; + timerToString(seconds) + &#39; ...&#39;
line_info = &#39;To stop the program, press Ctrl+E&#39;
len_line_timer = len(line_timer)
len_line_info = len(line_info)

In theory, this should work, but I do not know how to return the cursor pointer to the beginning of the line with a timer.
How can I return the cursor to the beginning of the timer line before output?

I want it to work like in Windows and Linux/Unix

Full code for playback

import time
len_line_timer = 0
len_line_info = 0
def timerToString(seconds: int) -&gt; str:
if seconds is not None:
seconds = int(seconds)
d = seconds // (3600 * 24)
h = seconds // 3600 % 24
m = seconds % 3600 // 60
s = seconds % 3600 % 60
if d &gt; 0:
return &#39;{:02d}d {:02d}h {:02d}m {:02d}s&#39;.format(d, h, m, s)
elif h &gt; 0:
return &#39;{:02d}h {:02d}m {:02d}s&#39;.format(h, m, s)
elif m &gt; 0:
return &#39;{:02d} minutes {:02d} seconds&#39;.format(m, s)
elif s &gt; 0:
return &#39;{:02d} seconds&#39;.format(s)
return &#39;now&#39;
def timer(seconds):
global len_line_timer
global len_line_info
clear_line_timer = &#39;&#39;.join(&quot; &quot; for i in range(len_line_timer))
clear_line_info = &#39;&#39;.join(&quot; &quot; for i in range(len_line_info))
line_timer = &#39;Next update data after &#39; + timerToString(seconds) + &#39; ...&#39;
line_info = &#39;To stop the program, press Ctrl+E&#39;
len_line_timer = len(line_timer)
len_line_info = len(line_info)
####################################################################################
# You need to somehow return the cursor pointer to the beginning of the timer line #
####################################################################################
print(clear_line_timer + &#39;\r&#39;, end=&#39;&#39;)
print(line_timer + &#39;\r&#39;, end=&#39;&#39;)
print(clear_line_info + &#39;\r&#39;, end=&#39;&#39;)
print(line_info + &#39;\r&#39;, end=&#39;&#39;)
if __name__ == &#39;__main__&#39;:
print(&quot;Important data 1&quot;)
print(&quot;Important data 2&quot;)
back_timer = 70
counter = back_timer
while True:
timer(counter)
counter -= 1
time.sleep(1)
if counter &lt;= 0:
counter = back_timer

答案1

得分: 0

FYI,这实际上不是一个python问题,更像是一个Linux shell问题(或者如果你在使用Windows的话,那就是Windows的问题)。

对于兼容bash的shell,有一些控制代码可以移动光标:https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html。只需像平常一样从python的STDOUT中print()这些代码即可。

你也可以查看https://pypi.org/project/ansi-escapes/,它正好可以做到这一点。

英文:

FYI, this isn't really a python question, more of a Linux shell question (or Windows, if that's what you're using).

For bash-compatible shells, there are control codes to move the cursor around: https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html. Just print() these codes to STDOUT from python as normal.

You can also check out https://pypi.org/project/ansi-escapes/ which does exactly this.

答案2

得分: 0

以下是要翻译的内容:

我在终端中使用这个bash函数来进行文本定位:

文本定位,用法:XY 10 10 'Hello World!'

XY () { printf "\e[$2;${1}H$3"; }

英文:

I'm using this bash function for text positioning in terminal:

# Text positioning, usage: XY 10 10 &#39;Hello World!&#39;
XY () { printf &quot;\e[$2;${1}H$3&quot;; }

huangapple
  • 本文由 发表于 2023年6月5日 12:19:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76403477.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定