【问题标题】:Print Text 'Loading' with dots going forward and backward in python shell在python shell中前后打印带有点的文本“加载”
【发布时间】:2017-06-17 14:54:54
【问题描述】:

我想打印文本 'Loading...' 但它的点会前后移动(在 shell 中)。

我正在创建一个文字游戏,因此它看起来会更好。
我知道慢慢写一个词,但点也必须回去。

我在想我应该忘记点回来。为此:

import sys
import time
shell = sys.stdout.shell
shell.write('Loading',"stdout")
str = '........'
for letter in str:
    sys.stdout.write(letter)
    time.sleep(0.1)

你怎么看?
如果你有那些点会前后移动那么请与我分享。
如果您想了解更多信息,我愿意提供给您。
谢谢

【问题讨论】:

  • shell 不是 sys.stdout 的属性,所以这不起作用。另外,文件描述符的 write 方法只需要一个参数。此外,您正在覆盖内置的“str”,这是一种不好的做法。因此,请编辑您的代码,至少提供一个工作示例(即使它没有达到您的预期)。
  • 链接将在 30 或 27 天后过期。

标签: python python-3.x shell


【解决方案1】:

您可以通过 STDOUT 中的退格键 (\b) 使用回溯返回并“擦除”写入的字符,然后再次写入它们以模拟动画加载,例如:

import sys
import time

loading = True  # a simple var to keep the loading status
loading_speed = 4  # number of characters to print out per second
loading_string = "." * 6  # characters to print out one by one (6 dots in this example)
while loading:
    #  track both the current character and its index for easier backtracking later
    for index, char in enumerate(loading_string):
        # you can check your loading status here
        # if the loading is done set `loading` to false and break
        sys.stdout.write(char)  # write the next char to STDOUT
        sys.stdout.flush()  # flush the output
        time.sleep(1.0 / loading_speed)  # wait to match our speed
    index += 1  # lists are zero indexed, we need to increase by one for the accurate count
    # backtrack the written characters, overwrite them with space, backtrack again:
    sys.stdout.write("\b" * index + " " * index + "\b" * index)
    sys.stdout.flush()  # flush the output

请记住,这是一个阻塞过程,因此您要么必须在 for 循环中进行加载检查,要么在单独的线程中运行加载,或者在单独的线程中运行 - 它会继续运行只要将其本地loading 变量设置为True,就属于阻塞模式。

【讨论】:

  • 可以flush 用于仅删除最后一个特定元素吗?我的意思是,如果我在 while 循环中打印两行直到键盘中断,它可以用来只删除最后一行吗?
  • @mini - 不要在模拟 shell 中运行它,而是在常规 shell/终端/命令提示符/任何脚本中运行它 (python your_script.py)。调试/测试环境并非旨在遵循常见的终端实践。
  • 它成功了。你太棒了。但我想用 Shell 运行它。
  • @Gahan - 您可以在大多数终端中通过 sys.stdout.write("\r" + " " * 80 + "\r") 将整行空白,假设终端宽度为 80 个字符。您不能(轻松)在大多数终端中回溯多行,如果您需要在整个屏幕上移动,我建议您使用 curses 模块。以this answer 为例。
  • @mini - 在 IDLE 中无法使用退格 (\b) 和回车 (\r) 控制字符是一个众所周知的长期存在的错误 (Issue #23220),并且没有你可以做很多事情。请记住,您的文字游戏的大多数用户甚至都不知道 IDLE 是什么,更不用说使用它了。他们将以与大多数 Python 程序相同的方式运行您的游戏——通过在其操作系统默认 shell 中运行 Python 解释器——并且在这些情况下可以正常工作。
【解决方案2】:

检查此模块Keyboard 的许多功能。安装它,也许用这个命令:

pip3 install keyboard

然后在textdot.py文件中编写如下代码:

def text(text_to_print,num_of_dots,num_of_loops):
    from time import sleep
    import keyboard
    import sys
    shell = sys.stdout.shell
    shell.write(text_to_print,'stdout')
    dotes = int(num_of_dots) * '.'
    for last in range(0,num_of_loops):
        for dot in dotes:
            keyboard.write('.')
            sleep(0.1)
        for dot in dotes:
            keyboard.write('\x08')
            sleep(0.1)

现在将文件粘贴到您的 python 文件夹中的 Lib 中。
现在你可以像下面的例子一样使用它:

import textdot
textdot.text('Loading',6,3)

谢谢

【讨论】:

    【解决方案3】:

    我相信下面的代码就是你要找的。只需将其线程化到您的脚本中,它就会在用户等待时闪烁点。

    ################################################################################
    """
    Use this to show progress in the terminal while other processes are runnning
                            - show_running.py -
    """
    ################################################################################
    #import _thread as thread
    import time, sys
    
    def waiting(lenstr=20, zzz=0.5, dispstr='PROCESSING'):
        dots   = '.' * lenstr
        spaces = ' ' * lenstr
        print(dispstr.center(lenstr, '*'))
        while True:
            for i in range(lenstr):
                time.sleep(zzz)
                outstr = dots[:i] + spaces[i:]
                sys.stdout.write('\b' * lenstr + outstr)
                sys.stdout.flush()
    
            for i in range(lenstr, 0, -1):
                time.sleep(zzz)
                outstr = dots[:i] + spaces[i:]
                sys.stdout.write('\b' * lenstr + outstr)   
                sys.stdout.flush()  
    #------------------------------------------------------------------------------#
    if __name__ == '__main__':
        import _thread as thread
        from tkinter import *
    
        root = Tk()
        Label(root, text="I'm Waiting").pack()
    
        start = time.perf_counter()
    
        thread.start_new_thread(waiting, (20, 0.5))
    
        root.mainloop()
    
        finish = time.perf_counter()
        print('\nYour process took %.2f seconds to complete.' % (finish - start))
    

    【讨论】:

      【解决方案4】:

      有点晚了,但对其他人来说并不那么复杂。

      import os, time                                 #import os and time
      def loading():                                  #make a function called loading
          spaces = 0                                      #making a variable to store the amount of spaces between the start and the "."
          while True:                                     #infinite loop
              print("\b "*spaces+".", end="", flush=True) #we are deleting however many spaces and making them " " then printing "."
              spaces = spaces+1                           #adding a space after each print
              time.sleep(0.2)                             #waiting 0.2 secconds before proceeding
              if (spaces>5):                              #if there are more than 5 spaces after adding one so meaning 5 spaces (if that makes sense)
                  print("\b \b"*spaces, end="")           #delete the line
                  spaces = 0                              #set the spaces back to 0
      
      loading()                                       #call the function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多