verigak / progress

Easy to use progress bars for Python
ISC License
1.41k stars 179 forks source link

Blinking while clearing #45

Closed naktinis closed 4 years ago

naktinis commented 6 years ago

I've noticed that the progress bar sometimes blinks when clearing. I think it's caused by this line in WritelnMixin:

print('\r\x1b[K', end='', file=self.file)

This control sequence introducer \x1b[K is supposed to clear the characters to the right of the cursor, while \r returns the cursor to the left.

At least in my case it is enough to use \r without clearing anything. The characters will get overridden. Changing the line to print('\r', end='', file=self.file) and I haven't noticed any side effects yet. But maybe I'm missing something obvious here?

Outcome of using \r\x1b[K: blinking

Outcome of using \r: not_blinking

So my suggestion would be to either simply use \r for "clearing" the line, or to at least let the user customize this via some parameter.

hargikas commented 5 years ago

The problem is what will happen if for some reason the printed line is smaller than the previous line (like (eta_td).

naktinis commented 5 years ago

@hargikas in probably 99% cases it will not be shorter as progress is normally non-decreasing. For all remaining cases I suggested to let people enable the forced clearing with a parameter.

hargikas commented 5 years ago

@hargikas in probably 99% cases it will not be shorter as progress is normally non-decreasing. For all remaining cases I suggested to let people enable the forced clearing with a parameter.

It happens when the process has a lot of start-up time. A process where it involves copying a database table, the connection and first results of the query take more time, than the return of the some rows. So in this case the (eta_td) starts with something like (1 day, 12:00:00) and then drops into minutes (0:10:00), and for the rest of the process you have garbage at the end of the string.

In my pull request I have create a "lazy" print that only prints when the output has changed. It hasn't eliminated the flickering, but it has reduced it a lot.

naktinis commented 5 years ago

@hargikas true, that could happen. Could we maybe delete only the extra characters? We could go back max(0, len(self.previous_line) - len(line)) times and then delete the remainder with [K. As in echo -e 'A long line of text\b\b\b\b\b\033[K something'. What do you think?

hargikas commented 5 years ago

Thank you! It is a good idea, and even in windows there is far less blinking now.

gKw11ktmeq

I made a commit in my git fork. Now it is up to the owner of the repository @verigak if he wants to PR it, or implement something similar.

verigak commented 4 years ago

This took a long time but with 12e46ed70209bdc3bb8ca1f0416039883b94e4e1 we are not using ANSI escape codes to clear the line any more. It keeps track of maximum width ever printed and adds some padding if needed. This should solve this issue.