Jak mogę stworzyć graficzny interfejs użytkownika z wieloma paskami postępu?

21

Piszę własny skrypt, aby pobrać wiele elementów (jednocześnie jeden element na polecenie) przy użyciu wgeti potrzebuję paska postępu. Obecnie używam zenity --progressdo moich pasków postępu, ale problem polega na tym, że podczas pobierania pojawia się wiele pasków postępu.

Chcę osiągnąć coś podobnego do okna dialogowego przesyłania plików w Nautilus:

Okno dialogowe przesyłania plików Ubuntu

Czy ktoś może wskazać mi właściwy kierunek, który program (programy) lub język (języki) to osiągną.

UWAGA: Mam podstawową wiedzę na temat skryptowania powłoki, niewiele więcej.

Rey Leonard Amorato
źródło
Próbowałeś axel-kapt? sudo apt-get install axel-kapt
Nagroda jest bliska końca. Proszę, nie zapomnij go przypisać, jeśli czujesz się usatysfakcjonowany moją odpowiedzią.
Glutanimate
Nie ma problemu, stary. Powodzenia w skrypcie!
Glutanimate

Odpowiedzi:

28

Rozwiązanie za pomocą YAD


Przegląd

Zenity nie było aktualizowane od dłuższego czasu. Na szczęście istnieje widelec o nazwie YAD z wieloma dodatkowymi funkcjami. Nie dotarł jeszcze do oficjalnych repozytoriów, ale możesz go zainstalować z PPA webupd8:

sudo add-apt-repository ppa:webupd8team/y-ppa-manager
sudo apt-get update
sudo apt-get install yad

Jedną z funkcji dodanych do YAD jest okno dialogowe z wieloma pasami postępu. Oto fragment instrukcji YAD dotyczący wielu pasków postępu:

Multi progress bars dialog options
--bar=LABEL[:TYPE]
  Add progress bar. LABEL is a text label for progress bar. TYPE is a progress bar type. Types are:
  NORM for normal progress bar, RTL for inverted progress bar and PULSE for pulsate progress bar.
--vertical
  Set vertical orientation of progress bars.
--align=TYPE
  Set alignment of bar labels. Possible types are left, center or right. Default is left.

Initial values for bars set as extra arguments. Each lines with progress data passed to stdin must be started
from N: where N is a number of progress bar. Rest is the same as in progress dialog.

Bardzo prosty skrypt z wieloma paskami postępu mógłby wyglądać następująco:

for i in {1..100}; do
   printf "1:$i\n2:$i\n3:$i\n"
   sleep 0.2
done | yad --multi-progress --bar="Bar 1":NORM --bar="Bar 2":NORM --bar="Bar 3":NORM

Tak wyglądałby wynik:

prosty skrypt postępu yad


Możemy dodawać opisy do pasków za pomocą #:

for i in {1..100}; do
   printf "1:$i\n2:$i\n3:$i\n"
   printf "1:#Progress 1 is at $i percent\n2:#Progress 2 is at $i percent\n3:#Progress 3 is at $i percent\n"
   sleep 0.2
done | yad --multi-progress --bar="Bar 1":NORM --bar="Bar 2":NORM --bar="Bar 3":NORM

Wynik:

wprowadź opis zdjęcia tutaj


Jeśli chcemy zaimplementować to w skrypcie pobierania wget, najpierw musimy zrobić kilka rzeczy:

  • znaleźć sposób na wyodrębnienie postępu pobierania i innych interesujących danych z wyjścia wget
  • znaleźć sposób na iterację wielu plików
  • znajdź sposób na przekazanie wszystkich informacji, które mamy, do jednego okna dialogowego yad

Uważam ten projekt za dość interesujący, więc usiadłem i skomponowałem skrypt, który powinien wykonać wszystkie powyższe czynności.


yad_wget

Oto, co wymyśliłem:

#!/bin/bash

# NAME:         yad_wget
# VERSION:      0.2
# AUTHOR:       (c) 2014 Glutanimate
# DESCRIPTION:  graphical frontend to wget in form of a yad script
# FEATURES:     - display progress of multiple simultaneous downloads
#               - set maximum number of simultaneous downloads
# DEPENDENCIES: yad
#
#               Install yad on Ubuntu with:
#
#                   sudo add-apt-repository ppa:webupd8team/y-ppa-manager
#                   sudo apt-get update
#                   sudo apt-get install yad
#
# LICENSE:      GNU GPLv3 (http://www.gnu.de/documents/gpl-3.0.en.html)
#
# NOTICE:       THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 
#               EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
#               PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR 
#               IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
#               AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 
#               PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
#               YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
#
#               IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY 
#               COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS 
#               PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 
#               INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE 
#               THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED 
#               INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE 
#               PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 
#               PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#
# USAGE:        yad_wget <space-delimited URLs>
#               Closing the yad dialog will terminate all downloads in progress

# Variables and settings

MAXDLS="5" # set maximum number of simultaneous downloads

URILIST="$@" # gets list of URIs from stdin
USAGE="$0 <space-delimited URLs>"

# Set GUI variables up
TITLE="YAD wget downloader"                 # dialog title
TEXT="<b>Downloads</b> in progress:"        # dialog text
ICON="emblem-downloads"                     # window icon (appears in launcher)
IMAGE="browser-download"                    # window image (appears in dialog)

#URILIST="http://proof.ovh.net/files/100Mb.dat http://speedtest.wdc01.softlayer.com/downloads/test10.zip http://cachefly.cachefly.net/100mb.test"

# Usage checks

if [[ -z "$URILIST" ]]
  then
      echo "Error: No arguments provided"
      echo "Usage: $USAGE"
      exit 1
fi


# download file and extract progress, speed and ETA from wget
# we use sed regex for this
# source: http://ubuntuforums.org/showthread.php?t=306515&page=2&p=7455412#post7455412
# modified to work with different locales and decimal point conventions
download(){
    wget  "$1" 2>&1 | sed -u \
    "s/.* \([0-9]\+%\)\ \+\([0-9,.]\+.\) \(.*\)/$2:\1\n$2:# Downloading at \2\/s, ETA \3/"
    RET_WGET="${PIPESTATUS[0]}"             # get return code of wget
    if [[ "$RET_WGET" = 0 ]]                # check return code for errors
      then
          echo "$2:100%"
          echo "$2:#Download completed."
      else
          echo "$2:#Download error."
    fi
}


# compose list of bars for yad
for URI in $URILIST; do                     # iterate through all URIs
    FILENAME="${URI##*/}"                   # extract last field of URI as filename
    YADBARS="$YADBARS --bar=$FILENAME:NORM" # add filename to the list of URIs
done

IFS=" "
COUNTER="1"
DYNAMIC_COUNTER="1"

# main
# iterate through all URIs, download them in the background and 
# pipe all output simultaneously to yad
# source: http://pastebin.com/yBL2wjaY

for URI in $URILIST; do
    if [[ "$DYNAMIC_COUNTER" = "$MAXDLS" ]] # only download n files at a time
      then
          download "$URI" "$COUNTER"        # if limit reached wait until wget complete
          DYNAMIC_COUNTER="1"               # before proceeding (by not sending download() to bg)
      else
          download "$URI" "$COUNTER" &      # pass URI and URI number to download()
          DYNAMIC_COUNTER="$[$DYNAMIC_COUNTER+1]"
    fi
    COUNTER="$[$COUNTER+1]"                 # increment counter
done | yad --multi-progress --auto-kill $YADBARS --title "$TITLE" \
--text "$TEXT" --window-icon "$ICON" --image "$IMAGE"

# ↑ launch yad multi progress-bar window

I tak to wygląda:

wprowadź opis zdjęcia tutaj

           wprowadź opis zdjęcia tutaj

Przeczytaj wszystkie komentarze, aby dowiedzieć się, jak działa skrypt, a jeśli masz jakieś pytania, nie wahaj się zapytać w komentarzach poniżej.


Edytować:

Dodałem obsługę ustawiania maksymalnej liczby jednoczesnych pobrań. Np. Dla MAXDLS="5":

wprowadź opis zdjęcia tutaj

Glutanimate
źródło
To bardzo obszerny i interesujący post i podoba mi się to, co widzę do tej pory. Dzięki za poświęcenie czasu na majstrowanie przy tym moim małym projekcie. :) P1: Co dzieje się z paskiem postępu ukończonych plików? Czy pozostają w oknie dialogowym, dopóki wszystko inne nie zostanie zrobione? Q2: Z tego, co widzę, nie ma możliwości anulowania poszczególnych operacji z okna dialogowego, prawda?
Rey Leonard Amorato,
1
+1 dla yad; to świetny pakiet. Pamiętaj, że --notificationon yadnie będzie działał na Ubuntu 13.04 i nowszych z powodu błędu 1305835 i błędu 1119420 (skorzystaj z linków i głosuj na błędy).
Paddy Landau
2
Aby mieć dodatkowe elementy sterujące, musisz przejść do GtkDialog, który pozwala robić prawie wszystko. Jest jednak o wiele bardziej zaangażowany. Społeczność PuppyLinux z niego korzysta.
DocSalvager
1
@ Glutanimate - Jedna krótka uwaga, aby uniknąć wielu nieporozumień: wiele odnośników na forach PuppyLinux odnosi się do „gtkdialog3” i „gtkdialog4”. Są to po prostu prostsze synonimy prawdziwych wersji GtkDialog i nawet nie są spójne. Pobrana wersja 0.8.3 jest najnowsza i jest dość stabilna. (Moderatorzy: Koniec z GtkDialog tutaj. Każdy zainteresowany powinien zadawać nowe pytania.)
DocSalvager
1
@ Glutanimate Używam od yadkilku miesięcy i jestem pod wielkim wrażeniem jego mocy. Twoja odpowiedź tutaj jest jednak absolutnie błyskotliwa i lata świetlne wyprzedzają moje własne paski postępu. Będę bardzo szybki, aby dostosować wgetpostępu kodu kreskowego do własnej aplikacji: askubuntu.com/questions/900319/... .
WinEunuuchs2Unix