英文:
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 = ''.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)
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) -> 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)
####################################################################################
# You need to somehow return the cursor pointer to the beginning of the timer line #
####################################################################################
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("Important data 1")
print("Important data 2")
back_timer = 70
counter = back_timer
while True:
timer(counter)
counter -= 1
time.sleep(1)
if counter <= 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 'Hello World!'
XY () { printf "\e[$2;${1}H$3"; }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论