簡體   English   中英

使用Python進行Sublime Text的進度條

[英]Progress bar in Sublime Text with Python

我在MacOSX上使用強大的Sublime Text 3編輯器來運行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中進度條的使用?

看一下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")

輸出:

進度條

作為另一種替代方案, 您可以使用狀態欄 設置狀態欄消息時,將清除上一個文本。 包控件在安裝包時也使用狀態欄。

例:

使用狀態欄的Sublime文本進度條

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!')

您可以使用以下方法創建可視進度條:



演示:

演示



碼:

@ GitHub

(通過在Command Palette中鍵入Progress Bar Demo來運行插件)



筆記:

有一個css文件控制mdpopups的樣式。 由於某種原因, color屬性沒有任何影響。

此外, mdpopups.show_popuplocation參數取值為-1 ,以便在插入符號位置設置彈出窗口。 否則,我不確定location如何影響彈出窗口,因為它只需要一個整數值。

我在下面的帖子中詢問過這些問題:

[概念證明]視覺進度欄

您可能正在尋找的是一種保持輸出消耗多行的方法。 您可以打印\\b (退格符)與以前打印的字符一樣多次。 我寫這個作為一個例子:

(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='')

嘗試運行它,您可以根據自己的需要進行調整。

您可以使用進度條庫。 位於: https//pypi.python.org/pypi/progressbar/2.3-dev

您也可以從easy_install安裝它,只需輸入: easy_install progressbar

使用示例:

如果你想要簡單的進度條,沒有關於功能的信息:

from progressbar import *
from time import sleep

progress = ProgressBar()
for i in progress(range(80)):
  sleep(0.01)

否則,如果您想要有關函數信息的進度條:

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的輸出面板中是不可能的。 該面板是不是真正的控制台或終端,和其他方面的差異不解釋轉義序列如間\\r\\b\\n然而正確地解釋)。 如果要查看其工作原理,請安裝PackageResourceViewer ,然后打開Packages/Default/exec.py

為了使其工作,您需要創建一個新的構建系統以在終端中運行它。 由於OS X的變幻莫測,您需要創建兩個文件。 第一個是shell腳本:

#!/bin/sh
osascript -e '    
  on run parameters        
    tell application "Terminal"            
      activate            
      do script with command "/path/to/python " & parameters        
    end tell    
  end run
' $@

使用python (或python3 )的實際路徑更改/path/to 將它保存在PythonTerminal.sh任何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文件,並與 建立。 將打開一個新的終端窗口,您的進度條應該會運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM