Fixed output when console is spinning

This commit is contained in:
Sven Heidemann 2021-03-05 17:09:12 +01:00
parent 0a630f9316
commit 562bb81379
3 changed files with 82 additions and 14 deletions

View File

@ -8,6 +8,7 @@ from tabulate import tabulate
from termcolor import colored from termcolor import colored
from cpl.console.background_color import BackgroundColor from cpl.console.background_color import BackgroundColor
from cpl.console.console_call import ConsoleCall
from cpl.console.foreground_color import ForegroundColor from cpl.console.foreground_color import ForegroundColor
from cpl.console.spinner_thread import SpinnerThread from cpl.console.spinner_thread import SpinnerThread
@ -21,6 +22,9 @@ class Console:
_y: Optional[int] = None _y: Optional[int] = None
_disabled: bool = False _disabled: bool = False
_hold_back = False
_hold_back_calls: list[ConsoleCall] = []
""" """
Properties Properties
""" """
@ -39,6 +43,10 @@ class Console:
Settings Settings
""" """
@classmethod
def set_hold_back(cls, value: bool):
cls._hold_back = value
@classmethod @classmethod
def set_background_color(cls, color: Union[BackgroundColor, str]): def set_background_color(cls, color: Union[BackgroundColor, str]):
if type(color) is str: if type(color) is str:
@ -95,16 +103,25 @@ class Console:
""" """
Useful public methods Useful public methods
""" """
@classmethod @classmethod
def banner(cls, string: str): def banner(cls, string: str):
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.banner, string))
return
ascii_banner = pyfiglet.figlet_format(string) ascii_banner = pyfiglet.figlet_format(string)
cls.write_line(ascii_banner) cls.write_line(ascii_banner)
@classmethod @classmethod
def clear(cls): def clear(cls):
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.clear))
return
os.system('cls' if os.name == 'nt' else 'clear') os.system('cls' if os.name == 'nt' else 'clear')
@classmethod @classmethod
@ -112,6 +129,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.close))
return
Console.reset() Console.reset()
Console.write('\n\n\nPress any key to continue...') Console.write('\n\n\nPress any key to continue...')
Console.read_line() Console.read_line()
@ -126,6 +147,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.error, string, tb))
return
cls.set_foreground_color('red') cls.set_foreground_color('red')
if tb is not None: if tb is not None:
cls.write_line(f'{string} -> {tb}') cls.write_line(f'{string} -> {tb}')
@ -139,14 +164,14 @@ class Console:
@classmethod @classmethod
def read(cls, output: str = None) -> str: def read(cls, output: str = None) -> str:
if output is not None: if output is not None and not cls._hold_back:
cls.write(output) cls.write(output)
return input()[0] return input()[0]
@classmethod @classmethod
def read_line(cls, output: str = None) -> str: def read_line(cls, output: str = None) -> str:
if cls._disabled: if cls._disabled and not cls._hold_back:
return '' return ''
if output is not None: if output is not None:
@ -164,6 +189,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.table, header, values))
return
table = tabulate(values, headers=header) table = tabulate(values, headers=header)
Console.write_line(table) Console.write_line(table)
@ -174,6 +203,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write, args))
return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
cls._output(string, end='') cls._output(string, end='')
@ -182,6 +215,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_at, x, y, args))
return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
cls._output(string, x, y, end='') cls._output(string, x, y, end='')
@ -190,6 +227,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_line, args))
return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
if not cls._is_first_write: if not cls._is_first_write:
cls._output('') cls._output('')
@ -200,6 +241,10 @@ class Console:
if cls._disabled: if cls._disabled:
return return
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_line_at, x, y, args))
return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
if not cls._is_first_write: if not cls._is_first_write:
cls._output('', end='') cls._output('', end='')
@ -207,14 +252,18 @@ class Console:
@classmethod @classmethod
def spinner(cls, message: str, call: Callable) -> any: def spinner(cls, message: str, call: Callable) -> any:
if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.spinner, message, call))
return
cls.write_line(message) cls.write_line(message)
spinner = SpinnerThread(cls) cls.set_hold_back(True)
spinner = SpinnerThread()
spinner.start() spinner.start()
return_value = call() return_value = call()
spinner.stop_spinning() spinner.stop_spinning()
cls.set_hold_back(False)
for call in cls._hold_back_calls:
call.function(*call.args)
return return_value return return_value
@classmethod
def flush(cls):
sys.stdout.flush()

View File

@ -0,0 +1,16 @@
from collections import Callable
class ConsoleCall:
def __init__(self, function: Callable, *args):
self._func = function
self._args = args
@property
def function(self):
return self._func
@property
def args(self):
return self._args

View File

@ -1,13 +1,13 @@
import sys
import threading import threading
import time import time
class SpinnerThread(threading.Thread): class SpinnerThread(threading.Thread):
def __init__(self, console): def __init__(self):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self._console = console
self._is_spinning = True self._is_spinning = True
@staticmethod @staticmethod
@ -17,16 +17,19 @@ class SpinnerThread(threading.Thread):
yield cursor yield cursor
def run(self) -> None: def run(self) -> None:
self._console.write('\t') print('\t', end='')
spinner = self._spinner() spinner = self._spinner()
while self._is_spinning: while self._is_spinning:
self._console.write(next(spinner)) # self._console.write(next(spinner))
print(next(spinner), end='')
time.sleep(0.1) time.sleep(0.1)
self._console.write('\b') # self._console.write('\b')
print('\b', end='')
self._console.flush() sys.stdout.flush()
self._console.write(' ') # self._console.write(' ')
print(' ', end='')
def stop_spinning(self): def stop_spinning(self):
self._is_spinning = False self._is_spinning = False