Optimize Progress Bar, again...

Fix "Changing Destination Path" bug, provided by YXRain05
This commit is contained in:
2023-04-30 22:14:52 +08:00
parent f0ce51e87d
commit dded74a4a9
5 changed files with 79 additions and 20 deletions

View File

@@ -2,17 +2,68 @@
from os import get_terminal_size
from progress.bar import Bar
from progress.colors import color
from modules.utils.length import get_more_length
from modules.utils.length import get_more_length, len_abs
class CompactBar(Bar):
def print_onto_bar(self, message: str):
print()
self.update()
print(f"\x1b[1A\x1b[{get_terminal_size().columns}D{(get_terminal_size().columns-1) * ' '}"
f"\x1b[{get_terminal_size().columns}D"+message[:(get_terminal_size().columns - get_more_length(message))])
self.update()
"""在进度条的上方打印消息,进度条保持在下方"""
# 光标移动到行首,并通过打印空格清空残留的进度条 ↓
print(f"\x1b[{get_terminal_size().columns}D{(get_terminal_size().columns - 1) * ' '}"
# 光标移动到该行的首部(\x1b[nD, n为前移个数),将需要的信息打印出来,再将光标移动到下一行 ↓
f"\x1b[{get_terminal_size().columns}D" + message)
self.update() # 更新进度条
def next_without_newline(self):
self.next()
def writeln(self, line, shorten=False):
"""覆写writeln配合修改过后的update"""
if self.file and self.is_tty():
width = len_abs(line)
if shorten:
self._max_width = shorten
elif width < self._max_width:
# Add padding to cover previous contents
line += ' ' * (self._max_width - width)
else:
self._max_width = width
print('\r' + line, end='', file=self.file)
self.file.flush()
def update(self):
"""
覆写原有的update方法自适应终端宽度
支持中文
"""
filled_length = int(self.width * self.progress)
empty_length = self.width - filled_length
message = self.message % self
bar = color(self.fill * filled_length, fg=self.color)
empty = self.empty_fill * empty_length
suffix = self.suffix % self
line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
suffix])
# 以上为原本update代码
term_size = get_terminal_size().columns
shorten = False
if len_abs(line) > term_size: # 检测完整长度是否小于终端长度
if len_abs(line) - len_abs(''.join([bar, empty])) <= term_size: # 检测无进度条时是否小于终端长度
width = term_size - (len_abs(line) - len_abs("".join([bar, empty]))) - 1
filled_length = int(width * self.progress)
empty_length = width - filled_length
bar = color(self.fill * filled_length, fg=self.color)
empty = self.empty_fill * empty_length
line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
suffix])
shorten = len_abs(line)
elif len_abs(''.join([message, suffix])) <= term_size: # 检测仅有前缀后缀时是否小于终端长度
line = ''.join([message, suffix])
shorten = len_abs(line)
else: # 全部不符合时,以仅有前缀后缀的模式,直接截断
display_length = term_size-get_more_length(''.join([message, suffix])[:term_size])-3
if display_length < 0:
display_length = 0
line = ''.join([message, suffix])[:display_length]+"..."
shorten = len_abs(line)
self.writeln(line, shorten=shorten)

View File

@@ -1,12 +1,11 @@
"""一些有关计算长度的工具"""
def len_abs(content):
"""针对中文将一个汉字识别为2个长度而不是1个"""
return len(content) + (len(content.encode("utf-8")) - len(content)) // 2
def get_more_length(content):
"""将相对于正常长度的超出值返回"""
return (len(content.encode("utf-8")) - len(content)) // 2
def len_abs(content):
"""针对中文将一个汉字识别为2个长度而不是1个"""
return len(content) + get_more_length(content)