Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: 'MrPoxipol'
Biblioteki C++

GtkProgressBar

[lekcja] Rozdział 13. Opisuje, w jaki sposób można utworzyć pasek postępu.

GtkProgressBar-Pasek postępu

Pasek postępu jest często używany, gdy nasz program wykonuje jakąś czasochłonną operację. Może on pokazywać ile procent zostało ukończone, ale także informować, że program nadal pracuje. W tej lekcji dowiemy się jak takowy pasek umieścić w naszej aplikacji.

Tworzenie ProgressBar’a

Stworzenie takiego widżetu sprowadza się do wywołania funkcji:
GtkWidget * gtk_progress_bar_new( void )


Już wiemy jak tworzy się pasek postępu. Teraz zobaczmy przykład użycia owego widżetu.
C/C++
#include <gtk/gtk.h>
#include <stdio.h>

void ChangeValue( GtkRange * widget, gpointer data )
{
    gdouble value = 0;
    gchar * text;
    GtkWidget * progressBar = GTK_WIDGET( data );
   
    value = gtk_range_get_value( GTK_RANGE( widget ) );
    gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR( progressBar ), value / 100 );
    text = g_strdup_printf( "%d%%",( int ) value );
    gtk_progress_bar_set_text( GTK_PROGRESS_BAR( progressBar ), text );
   
    g_free( text );
}

int main( int argc, char * argv[] )
{
    GtkWidget * window;
    GtkWidget * vbox;
    GtkWidget * progressBar;
    GtkWidget * scale;
   
    gtk_init( & argc, & argv );
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
   
    progressBar = gtk_progress_bar_new();
    scale = gtk_hscale_new_with_range( 0, 100, 1 );
   
    gtk_progress_bar_set_text( GTK_PROGRESS_BAR( progressBar ), "0%" );
   
    vbox = gtk_vbox_new( FALSE, 0 );
    gtk_container_border_width( GTK_CONTAINER( vbox ), 5 );
    gtk_container_add( GTK_CONTAINER( window ), vbox );
    gtk_box_pack_start( GTK_BOX( vbox ), progressBar, TRUE, TRUE, 0 );
    gtk_box_pack_start( GTK_BOX( vbox ), scale, FALSE, FALSE, 0 );
   
    g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
    g_signal_connect( G_OBJECT( scale ), "value-changed", G_CALLBACK( ChangeValue ), progressBar );
   
    gtk_widget_show_all( window );
    gtk_main();
   
    return 0;
}
A więc tak. Tworzymy nowe standardowe okno i progress bar.

Dodajemy poziomą skalę (coś jak widżet ustawiania głośności) funkcją:
GtkWidget * gtk_hscale_new_with_range( gdouble min, gdouble max, gdouble step )

Pierwszy argument to minimum, drugi maksimum, a trzeci to krok o jaki skala będzie się przesuwać, gdy użyjemy klawiatury.

Napis na pasku ustawiamy wywołując:
void gtk_progress_bar_set_text( GtkProgressBar * pbar, const gchar * text )
 
Pierwszy argument to nasz progress bar, drugi to tekst, który chcemy ustawić.

W dalszej części ustawiamy wszystko w kontenerach, ustawiamy sygnał zamknięcia okna oraz zmiany wartości skali.
Używamy do tego sygnału "value-changed". Gdy wartość zostanie zmieniona wywołujemy funkcję
ChangeValue
 i, aby operować na pasku, podajemy go jako argument naszej funkcji.

Czas teraz na można by rzec "serce naszego programu", czyli
void ChangeValue( GtkRange * widget, gpointer data )
.

gdouble gtk_range_get_value( GtkRange * range )
zwraca nam aktualną wartość na jaką jest ustawiona skala.

Kolejną przydatną (i raczej najważniejszą) rzeczą jest funkcja
void gtk_progress_bar_set_fraction( GtkProgressBar * pbar, gdouble fraction )

Ustawia ona wypełnienie paska postępu. Pierwszy argument tej funkcji to widżet paska, a drugi to wypełnienie, które może przyjąć wartości od 0.0 do 1.0.

Dzięki
g_strdup_printf()
 zamieniamy liczby na tekst. Następnie ustawiamy wcześniej przygotowany napis na pasku i funkcją
g_free()
 zwalniamy pamięć.

Nasz pierwszy ProgressBar w GTK+
Nasz pierwszy ProgressBar w GTK+

Pulsujący ProgressBar

Może zajść potrzeba, kiedy to nie wiadomo ile pracy przez program ma być wykonane. W takim momencie dobrze jest użyć pulsującego paska postępu.

Po tym przykładzie i analizie znajdującej się poniżej będziesz już wiedzieć jak takowy wykonać.

C/C++
#include <gtk/gtk.h>

gboolean pulse( gpointer data )
{
    gtk_progress_bar_pulse( GTK_PROGRESS_BAR( data ) );
    return TRUE;
}
int main( int argc, char * argv[] )
{
    GtkWidget * window;
    GtkWidget * progressBar;
   
    gtk_init( & argc, & argv );
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
   
    progressBar = gtk_progress_bar_new();
   
    gtk_container_add( GTK_CONTAINER( window ), progressBar );
    g_timeout_add( 90,( GSourceFunc ) pulse, progressBar );
   
    g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
   
    gtk_widget_show_all( window );
    gtk_main();
   
    return 0;
}

Program pokazuje pulsujący pasek postępu.
Tworzymy nowy pasek.
Funkcją
guint g_timeout_add( guint interval, GSourceFunc function, gpointer data )
 
ustawiamy regularne wykonanie funkcji co określony czas. Kończy ona swoje działanie, gdy wykonywana funkcja zwróci wartość
FALSE
. Pierwszy argument to opóźnienie w ms, drugi to nazwa funkcji, a trzeci wskaźnik, który chcemy przekazać(są nim widżety).

W
gboolean pulse( gpointer data )
 

Funkcja
void gtk_progress_bar_pulse( GtkProgressBar * pbar )
 
Przesuwa „bloczek” o krok, którego wartość można ustalić dodatkową funkcją (https://developer.gnome.org/gtk3/3.4/GtkProgressBar.html#gtk-progress-bar-set-pulse-step)

Pulsujący ProgressBar
Pulsujący ProgressBar

Podsumowanie

To by już było na tyle, jeśli chodzi o Progress Bar’y.

Zapamiętaj

Pasek postępu potrzebuje dodatkowego wątku w programie, aby postęp był widoczny, gdy pierwszy wątek będzie zajęty, a nie utworzyliśmy drugiego dla paska, nie uzyskamy pożądanego efektu.
Poprzedni dokument Następny dokument
GtkTreeView Tworzenie aplikacji obsługującej wiele języków