Индикатор выполнения в Sublime Text с Python
Я использую мощный редактор Sublime Text 3 на MacOSX для запуска кодов python. Я хочу отобразить индикатор выполнения цикла for и следующую команду:
sys.stdout.write('rProgress : %03.2f %%' % (100*float(i)/(N)))
sys.flush()
не очищает ранее напечатанную строку в окне вывода, Как ожидалось (r
), но производит N
строки:
Progress : 0.25 %
Progress : 0.50 %
Progress : 0.75 %
Progress : 1.00 %
Progress : 1.25 %
Progress : 1.50 %
Progress : 1.75 %
Progress : 2.00 %
Progress : 2.25 %
Progress : 2.50 %
...
что не очень приятно читать – я делаю вывод, что окно вывода может быть только для чтения.
есть ли у кого-нибудь предложения по улучшению использования прогресс-бары в Sublime Text?
6 ответов
посмотреть sublime.py
мы видим, что flush
метод фактически ничего не делает:
class _LogWriter:
def flush(self):
pass
def write(self, s):
sublime_api.log_message(s)
sys.stdout = _LogWriter()
sys.stderr = _LogWriter()
однако я бы не рекомендовал использовать консоль для пользовательских выходов в любом случае. Обычно вы используете панели вывода / представления или сообщения о состоянии.
сообщения о состоянии проще в использовании, но менее мощные. sergioFC продемонстрировал это в ответ.
это демонстрирует, как использовать панель вывода. Это очень гибкий, но вы должны написать свой собственный текст команда для вставки текста. Это необходимо, поскольку для изменения содержимого представления требуется объект редактирования.
import sublime
import sublime_plugin
class MyInsertProgressBarCommand(sublime_plugin.TextCommand):
def run(self, edit, value):
view = self.view
width, _ = view.viewport_extent()
em_width = view.em_width()
# the number of columns are the width divided by the width of a char
# subtract two to add a little border
columns = int(width / em_width) - 2
# subtract two, because we surround it with [ and ]
bar_length = columns - 2
# calculate the size of the filled and the remaining part
filled_length = int(bar_length * value / 100)
remaining_length = bar_length - filled_length
# assemble the string for the progress bar
text = "[{0}{1}]\n".format("=" * filled_length, "." * remaining_length)
# add the text for the percentages
if value >= 100:
percentage_text = "finished!"
else:
percentage_text = "{:3.2f} %".format(value)
text += " " * (columns - len(percentage_text)) + percentage_text
# replace the content of the view
view.replace(edit, sublime.Region(0, view.size()), text)
# reset sels
view.sel().clear()
view.sel().add(sublime.Region(0, 0))
class ProgressBarCommand(sublime_plugin.WindowCommand):
def run(self):
self.window.create_output_panel("progess_bar")
self.window.run_command("show_panel", {"panel": "output.progess_bar"})
def test_progress_bar():
import random
test_progress_bar.value += 2 * random.random()
if test_progress_bar.value >= 100:
self.finish_progress()
return
self.show_progress(test_progress_bar.value)
sublime.set_timeout(test_progress_bar, 100)
test_progress_bar.value = 0
sublime.set_timeout_async(test_progress_bar, 1)
def show_progress(self, progess):
view = self.window.find_output_panel("progess_bar")
view.run_command("my_insert_progress_bar", {"value": progess})
def finish_progress(self):
self.show_progress(100)
sublime.set_timeout(self._destroy, 5000)
def _destroy(self):
self.window.destroy_output_panel("progess_bar")
вывод:
вы можете создать визуальный индикатор выполнения, используя:
- the mdpopups библиотека
-
sublime.set_timeout
илиsublime.set_timeout_async
( см.: Возвышенный Модуль )
демо:
код:
@ На GitHub
( запустите плагин, введя Progress Bar Demo
@ палитра команд)
Примечания:
есть css файл, который контролирует стиль mdpopups
.
По какой-то причине color
свойство не оказывает никакого эффекта.
и mdpopups.show_popup
' s
как еще одно альтернативное решение вы можете использовать строку состояния. При установке сообщения строки состояния предыдущий текст очищается. контрольный пакет также используется в строке состояния при установке пакетов.
пример:
import sublime, sublime_plugin
import time
class ExampleCommand(sublime_plugin.WindowCommand):
def run(self, args):
sublime.set_timeout_async(self.test,1)
def test(self):
i=80
while i <= 100:
sublime.status_message('%03.2f %%' % i)
time.sleep(0.15)
i+=0.25
sublime.status_message('100% Stackoverflow!')
то, что вы можете искать, - это способ сохранить вывод от потребления нескольких строк. Вы можете распечатать \b
(символ backspace) столько раз, сколько было ранее напечатанных символов. Я написал это в качестве примера:
(Python 2.7.6)
from __future__ import print_function
import time, sys
for i in range(1, 6):
print(i, end='')
sys.stdout.flush()
time.sleep(0.5)
print('\b', end='')
попробуйте запустить это, и вы можете адаптировать его к своим потребностям.
вы можете использовать библиотеку progressbar. находится здесь : https://pypi.python.org/pypi/progressbar/2.3-dev
также вы можете установить его из easy_install просто введите:easy_install progressbar
пример использования :
Если вы хотите простой progressbar с информацией о функции:
from progressbar import *
from time import sleep
progress = ProgressBar()
for i in progress(range(80)):
sleep(0.01)
else если вы хотите progressbar с информацией о функции:
from progressbar import *
from time import sleep
widgets = ['Something: ', Percentage(), ' ', Bar(marker=RotatingMarker()),
' ', ETA(), ' ', FileTransferSpeed()]
pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
for i in range(1000000):
# do something
pbar.update(10*i+1)
sleep(0.000001)
pbar.finish()
к сожалению, это невозможно в выходной панели Sublime. Панель не является истинной консолью или терминалом, и среди других различий не интерпретирует escape-последовательности, такие как \r
и \b
(\n
и правильно интерпретированы). Если вы хотите посмотреть, как именно это работает, установите PackageResourceViewer
, затем откройте Packages/Default/exec.py
.
чтобы заставить это работать, вам нужно создать новый построить систему запустить его в Терминал. Из-за капризов OS X вам нужно будет создать два файла. Первый скрипт:
#!/bin/sh
osascript -e '
on run parameters
tell application "Terminal"
activate
do script with command "/path/to/python " & parameters
end tell
end run
' $@
изменить /path/to
С вашим фактическим путем к python
(или python3
). Сохраните его, где вы хотите, как PythonTerminal.sh
. Далее выберите Tools -> Build System -> New Build System
и вставьте следующее:
{
"cmd": ["/bin/sh /path/to/Python3Terminal.sh \"$file\""],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"shell": true
}
еще раз, изменить /path/to
к фактическому пути к PythonTerminal.sh
. Сохраните файл как Packages/User/PythonTerminal.sublime-build
(он должен автоматически открывать нужный каталог при экономия.)
наконец, выберите Tools -> Build System -> PythonTerminal
, переключитесь на файл Python и создайте с помощью ⌘B. Откроется новое окно терминала, и ваш индикатор выполнения должен работать.