Heim > Backend-Entwicklung > Golang > Wie erstelle ich mit mpb einen zweizeiligen Fortschrittsbalken?

Wie erstelle ich mit mpb einen zweizeiligen Fortschrittsbalken?

WBOY
Freigeben: 2024-02-06 08:51:08
nach vorne
851 Leute haben es durchsucht

Wie erstelle ich mit mpb einen zweizeiligen Fortschrittsbalken?

问题内容

我正在尝试用 mpb 制作两行进度条。

假设我有一个包含文件绝对路径的切片。

list := []string{"c:\temp\01.png",  "c:\temp\02.png",  "c:\temp\03.png",  "c:\temp\test.png",  "c:\temp\test01.png"}
Nach dem Login kopieren

我希望它像这样显示:

processing 01.png ...
0 / 5 [                    ] 0%
Nach dem Login kopieren
processing 02.png ...
1 / 5 [==                  ] 20%
Nach dem Login kopieren
processing 03.png ...
2 / 5 [====                ] 40%
Nach dem Login kopieren

等等。

将“正在处理...”部分和进度条分开的原因是:

  1. 我想显示有关当前处理状态的附加信息。
    processing 01.png ... [mode: webp]
    0 / 5 [                    ] 0%
    Nach dem Login kopieren
  2. 有时,我必须处理同一个文件两次。
    processing 01.mp4 ... [mode: webm] [pass: 1/2]
    0 / 5 [                    ] 0%
    Nach dem Login kopieren
    processing 01.mp4 ... [mode: webm] [pass: 2/2]
    0 / 5 [                    ] 0%
    Nach dem Login kopieren
    请注意,进度条未更改。
  3. 我也想一次制作多个进度条。
    Processing 01.mp4 ... [Mode: WebM] [Pass: 1/2]
    4 / 5 [================    ] 0%
    Processing 01.png ... [Mode: WebP]
    2 / 5 [========            ] 0%
    Processing DONE [Mode: MP3]
    5 / 5 [====================] 100%
    Nach dem Login kopieren
    当事情发生变化时,每个进度条都应该尽快更新,而不是“每 0.5 秒更新每个进度条”。

我找不到这样做的方法。 mpb 的每个示例代码都是在单行中完成其工作。


正确答案


我第一次看到这个库,但在探索了一些代码之后,我发现了如何根据我们的需要添加新的和自定义的栏。我对您在评论中提供的链接示例进行了一些修改,以演示添加和自定义栏。

package main

import (
    "fmt"
    "io"
    "math/rand"
    "time"

    "github.com/vbauerster/mpb/v8"
    "github.com/vbauerster/mpb/v8/decor"
)

func main() {
    p := mpb.new()

    var piece, piece2 int64

    var way, way2 int64

    file := func(_ decor.statistics) string {

        return "file.extension "
    }

    file2 := func(_ decor.statistics) string {

        return "file2.extension "
    }

    part := func(s decor.statistics) string {

        s.current = piece
        s.total = 5
        return fmt.sprintf(" part %d/%d", s.current, s.total)
    }

    part2 := func(s decor.statistics) string {

        s.current = piece2
        s.total = 10
        return fmt.sprintf(" part %d/%d", s.current, s.total)
    }

    pass := func(s decor.statistics) string {

        s.current = way
        s.total = 2
        return fmt.sprintf(" pass %d/%d", s.current, s.total)
    }

    pass2 := func(s decor.statistics) string {

        s.current = way2
        s.total = 4
        return fmt.sprintf(" pass %d/%d", s.current, s.total)
    }
    var total = 100

    bar := p.new(int64(total),
        mpb.nopstyle(), // make main bar style nop, so there are just decorators
        mpb.barextender(extended(mpb.barstyle().build()), false), // extend wtih normal bar on the next line
        mpb.prependdecorators(
            decor.any(file),
            decor.name("percentage: "),
            decor.newpercentage("%d"),
            decor.any(part),
            decor.any(pass),
        ),
    )

    bar2 := p.new(int64(total+100),
        mpb.nopstyle(),
        mpb.barextender(extended(mpb.barstyle().build()), false),

        mpb.prependdecorators(
            decor.any(file2),
            decor.name("percentage: "),
            decor.newpercentage("%d"),
            decor.any(part2),
            decor.any(pass2),
        ),
    )
    // simulating some work
    max := 100 * time.millisecond

    for i := 0; i < total+100; i++ {

        switch {
        case i == 20 || i == 40 || i == 60 ||
            i == 80 || i == 100 || i == 120 ||
            i == 140 || i == 160 || i == 180:
            piece2++

            if i == 100 {
                way2++

                piece = 5
                way = 2
            } else if i < 100 {
                piece++
            }

        case i == 50 || i == 150:

            if i < 100 {
                way++
            }

            way2++
        }

        time.sleep(time.duration(rand.intn(10)+1) * max / 10)

        if i < 100 {
            bar.increment()
        }
        bar2.increment()
    }

    way2 = 4
    piece2 = 10
    // wait for our bar to complete and flush
    p.wait()
}

func extended(base mpb.barfiller) mpb.barfiller {
    return mpb.barfillerfunc(func(w io.writer, st decor.statistics) error {
        err := base.fill(w, st)
        if err != nil {
            return err
        }
        _, err = io.writestring(w, "\n")
        return err
    })
}
Nach dem Login kopieren

假设您已经知道如何制作自定义装饰器。

要创建一个新栏,您可以执行以下操作:

bar := p.new(int64(total),
        mpb.nopstyle(), // make main bar style nop, so there are just decorators
        mpb.barextender(extended(mpb.barstyle().build()), false), // extend wtih normal bar on the next line
        mpb.prependdecorators(
            decor.any(file),
            decor.name("percentage: "),
            decor.newpercentage("%d"),
            decor.any(part),
            decor.any(pass),
        ),
    )
Nach dem Login kopieren

例如,我只制作了两个金条,但您制作了两个以上。

在这个示例中,为了演示如何制作新栏,我使用了 new() 方法,但经过一些研究后,我发现还有更多方法可以制作新栏。区别主要在于酒吧的外观。您可以通过在 文档

p.new() 的第一个参数用于定义条形的总值,在该条形中为 100。

只需将您的装饰器/部分放入 mpb.prependdecoratorsmpb.appenddecorators 即可。

mpb.prependdecorators(
            decor.any(file),
            decor.name("percentage: "),
            decor.newpercentage("%d"),
            decor.any(part),
            decor.any(pass),
        ),
Nach dem Login kopieren

您可以为每个栏使用相同的装饰器,但我建议为每个栏创建新的装饰器以避免发生冲突的可能性。

这将分别显示文件名、百分比、部分和通过:

file.extension percentage: 100% part 5/5 pass 2/2  
[==============================================================================]
Nach dem Login kopieren

在此示例中,每个装饰都会根据其循环中的设置值增加 1,循环遍历条形的总值。在这个栏中,我只是迭代了 1 到 100。我的目标是 100 到 5 个部分。当循环变量遇到100中的5个部分之一时,条形的part装饰会增加1。
而当达到50时,pass装饰就会增加1。

for i := 0; i < total+100; i++ {

        switch {
        case i == 20 || i == 40 || i == 60 ||
            i == 80 || i == 100 || i == 120 ||
            i == 140 || i == 160 || i == 180:
            piece2++

            if i == 100 {
                way2++

                piece = 5
                way = 2
            } else if i < 100 {
                piece++
            }

        case i == 50 || i == 150:

            if i < 100 {
                way++
            }

            way2++
        }

        time.sleep(time.duration(rand.intn(10)+1) * max / 10)

        if i < 100 {
            bar.increment()
        }
        bar2.increment()
    }
Nach dem Login kopieren

这个循环也适用于第二个小节。我只是将两个条形的增量状态组合在一个循环中以使代码更短。如果循环变量小于 100,则增加第一个柱的状态。当它达到100时,将所有装饰全部增加到总数,然后继续增加第二个栏的状态,直到循环结束。循环完成后,完成第二个条形增量的其余部分以达到总计。

65bd2e1fcfff

第二个栏包含 10 个零件和 4 个通道,总价值为 200。

整个代码的输出是:

file.extension percentage: 9% part 0/5 pass 0/2  
[======>-----------------------------------------------------------------------]
file2.extension percentage: 4% part 0/10 pass 0/4  
[===>--------------------------------------------------------------------------]
Nach dem Login kopieren
file.extension percentage: 49% part 2/5 pass 0/2  
[=====================================>----------------------------------------]
file2.extension percentage: 24% part 2/10 pass 0/4  
[==================>-----------------------------------------------------------]
Nach dem Login kopieren
file.extension percentage: 100% part 5/5 pass 2/2  
[==============================================================================]
file2.extension percentage: 74% part 7/10 pass 2/4  
[=========================================================>--------------------]
Nach dem Login kopieren
file.extension Percentage: 100% Part 5/5 Pass 2/2  
[==============================================================================]
file2.extension Percentage: 100% Part 10/10 Pass 4/4  
[==============================================================================]
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie erstelle ich mit mpb einen zweizeiligen Fortschrittsbalken?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage