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

Tworzenie GUI - kontrolki GtkCheckButton i GtkRadioButton

[lekcja] Rozdział 3. W rozdziale przedstawiono w jaki sposób korzystać z kontrolek GtkCheckButton i GtkRadioButton oraz jak je obsługiwać w kodzie programu.
Mając utworzone podstawowe okno, utwórz:
1. Utwórz kontener Pionowa skrzynka składający się z 2 elementów.
2. Utwórz w górnym elemencie poprzedniego kontenera, kontener Pozioma skrzynka składający się z 2 elementów, oraz ustaw we właściwościach w zakładce Ogólne, parametr Jednorodny na wartość Tak.
Zapisz projekt pod nazwą kurs3.ui.

Następnie w kontenerze pozimiego pola hbox2 ustaw:
W zakładce Pakowanie wartości Dopełnienie, Rozszerzanie, Wypełnianie na wartości takie jak na rysunku powyżej.

1. Utwórz Pionową skrzynkę z przyciskami (GtkVButtonBox) składającą się z 3 elementów w utworzonej wcześniej 2 elementowej poziomej skrzynce, w miejscah tak jak na rysunku.
2. Utwórz Pasek stanu w miejscu wskazanym na rysunku.

1. Wstaw Przełączniki w pierwszą pionową skrzynkę przycisków.
2. Wstaw Przełączniki radiowe w drugą pionową skrzynkę przycisków.

Zmień kolejno etykietę przełącznikom, w miejscu zaznaczonym czerwoną ramką.

Zakładamy, że domyślnie aktywną kontrolką będzie radiobutton1, dlatego nie należy zmieniać jej ustawień. Aby przełączniki radiowe zachowywały się w zamierzony sposób podczas przełączania wykonaj:
Zastosuj poniższe czynności dla kontrolek radiobutton2 i radiobutton3:
1. W zakładce Ogólne kontrolki ustaw opcję Aktywny na Nie.
2. Wybierz przycisk ... pojawi się okno.
3. W tym oknie wybierz radiobutton1, a następnie wciśnij przycisk OK.

Kontrolka radiobutton3 powinna mieć ustawiona wartości:


Po wykonaniu wszystkich powyższych czyności zawartość pliku kurs3.ui:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="window">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">window</property>
    <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkHBox" id="hbox2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="homogeneous">True</property>
            <child>
              <object class="GtkVButtonBox" id="vbuttonbox1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkCheckButton" id="checkbutton1">
                    <property name="label" translatable="yes">Opcja 1</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="draw_indicator">True</property>
                    <signal name="toggled" handler="on_checkbutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkCheckButton" id="checkbutton2">
                    <property name="label" translatable="yes">Opcja 2</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="draw_indicator">True</property>
                    <signal name="toggled" handler="on_checkbutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">1</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkCheckButton" id="checkbutton3">
                    <property name="label" translatable="yes">Opcja 3</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="draw_indicator">True</property>
                    <signal name="toggled" handler="on_checkbutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">2</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkVButtonBox" id="vbuttonbox2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkRadioButton" id="radiobutton1">
                    <property name="label" translatable="yes">Opcja pierwsza</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="active">True</property>
                    <property name="draw_indicator">True</property>
                    <signal name="toggled" handler="on_radiobutton_toggled" swapped="no"/>
                    <signal name="group-changed" handler="on_radiobutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkRadioButton" id="radiobutton2">
                    <property name="label" translatable="yes">Opcja druga</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="draw_indicator">True</property>
                    <property name="group">radiobutton1</property>
                    <signal name="toggled" handler="on_radiobutton_toggled" swapped="no"/>
                    <signal name="group-changed" handler="on_radiobutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">1</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkRadioButton" id="radiobutton3">
                    <property name="label" translatable="yes">Opcja trzecia</property>
                    <property name="use_action_appearance">False</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="draw_indicator">True</property>
                    <property name="group">radiobutton1</property>
                    <signal name="toggled" handler="on_radiobutton_toggled" swapped="no"/>
                    <signal name="group-changed" handler="on_radiobutton_toggled" swapped="no"/>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">False</property>
                    <property name="position">2</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="padding">5</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkStatusbar" id="statusbar1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="spacing">2</property>
            <property name="has_resize_grip">False</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>


Zawartość pliku funkcjezwrotne.h:
C/C++
#include <gtk/gtk.h>

void on_checkbutton_toggled( GtkToggleButton * togglebutton, gpointer user_data );
void on_radiobutton_toggled( GtkToggleButton * togglebutton, gpointer user_data );

Zawartość pliku funkcjezwrotne.c:
C/C++
#include "funkcjezwrotne.h"

extern GtkWidget * status;

const gchar * opcje[] = {
    "pierwszą",
    "drugą",
    "trzecią"
};


void wyswietl( guchar opcja )
{
    gchar komunikat[ 60 ];
    guint bit;
    guint ilosc_opcji = 0;
   
    /* Kopiuje do tablicy koumunikat łańcuch "Wybrano opcje checkbox: " */
    g_stpcpy( komunikat, "Wybrano opcje checkbox: " );
   
    /* Zlicznie ilosci opcji. Poniewaz opcja jest 8 bitowa, warunkiem skonczenia petli mogla by byc wartosc 8 */
    for( bit = 0; bit < 3; bit++ )
    {
        if(( opcja &( 1 << bit ) ) )
             ilosc_opcji++;
       
    }
   
    for( bit = 0; bit < 3; bit++ )
    {
        if(( opcja &( 1 << bit ) ) )
        {
            g_strlcat( komunikat, opcje[ bit ], - 1 );
            if( ilosc_opcji-- > 1 )
                 g_strlcat( komunikat, ", ", - 1 );
           
        }
    }
   
    g_strlcat( komunikat, ".", - 1 );
   
    /* Wyświetlenie odpowiedniego komunikatu na pasku stanu */
    gtk_statusbar_push( GTK_STATUSBAR( status ), 0, komunikat );
}


void on_checkbutton_toggled( GtkToggleButton * togglebutton, gpointer user_data )
{
    static guchar bajt_opcji = 0;
    const gchar * tekst;
    gint opcja_numer;
   
    /* Pobiera zawartość tekstu wybranej kontrolki GtkCheckButton */
    tekst = gtk_button_get_label( GTK_BUTTON( togglebutton ) );
   
    /* Pobiera z obiektu wartość identyfikowaną przez daną opcja */
    opcja_numer = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( togglebutton ), "opcja" ) );
   
    bajt_opcji ^= 1 << opcja_numer;
   
    g_print( "Zmiana opcji nr %d, wartość %d, '%s'.\n", opcja_numer, bajt_opcji, tekst );
   
    wyswietl( bajt_opcji );
}

void on_radiobutton_toggled( GtkToggleButton * togglebutton, gpointer user_data )
{
    GSList * grupa;
    gint pozycja;
   
    if( gtk_toggle_button_get_active( togglebutton ) )
    {
        grupa = gtk_radio_button_get_group( GTK_RADIO_BUTTON( togglebutton ) );
        pozycja = g_slist_index( grupa, GTK_RADIO_BUTTON( togglebutton ) );
        g_print( "Wybrano %d\n", pozycja );
    }
   
    switch( pozycja )
    {
    case 2:
        gtk_statusbar_push( GTK_STATUSBAR( status ), 0, "Opcja Radio nr 1" );
        break;
    case 1:
        gtk_statusbar_push( GTK_STATUSBAR( status ), 0, "Opcja Radio nr 2" );
        break;
    case 0:
        gtk_statusbar_push( GTK_STATUSBAR( status ), 0, "Opcja Radio nr 3" );
        break;
    }
}


Zawartość pliku main.c:
C/C++
#include <gtk/gtk.h>
#include "funkcjezwrotne.h"

/* Definicja pliku z zawartością GUI */
#define UI_FILE "kurs3.ui"

const gchar * nazwy_opcji[] = {
    "checkbutton1",
    "checkbutton2",
    "checkbutton3"
};

/* Zmienna globalna na potrzeby funkcji zawartych w funkcjezwrotne.c */
GtkWidget * status;


GtkWidget * utworz_okno( void )
{
    GtkWidget * okno;
    GtkWidget * opcje_check;
    GtkBuilder * builder;
    GError * error = NULL;
    guint i;
   
    /* Tworzy obiekt buildera */
    builder = gtk_builder_new();
    /* Wczytuje zawartość interfejsu i sprawdza ewentualne błędy */
    if( !gtk_builder_add_from_file( builder, UI_FILE, & error ) )
    {
        g_warning( "Nie można wczytać plilu buildera: %s", error->message );
        g_error_free( error );
    }
   
    /* Łączy sygnały zawarte w pliku interfejsu z odpowiednimi funkcjami */
    gtk_builder_connect_signals( builder, NULL );
   
    /* Pobiera obiekt z nazwą "window1" */
    okno = GTK_WIDGET( gtk_builder_get_object( builder, "window1" ) );
   
    /* W pętli pobierane są wskaźniki na kolejne kontrolki GtkCheckButton, następnie dodawana jest im dodatkow "właściwość" opcja i przypisywana jest jej konkretna wartość */
    for( i = 0; i < 3; i++ )
    {
        opcje_check = GTK_WIDGET( gtk_builder_get_object( builder, nazwy_opcji[ i ] ) );
        /* Dodanie obiektowi dodatkowej zmiennej identyfikowanej nazwą opcja, wartości i */
        g_object_set_data( G_OBJECT( opcje_check ), "opcja", GINT_TO_POINTER( i ) );
    }
   
   
    status = GTK_WIDGET( gtk_builder_get_object( builder, "statusbar1" ) );
   
    /* Obiekt buildera nie będzie już nam potrzebny, więc go "zwalniamy" */
    g_object_unref( builder );
   
    return okno;
}


int main( int argc, char * argv[] )
{
    GtkWidget * okno;
   
    gtk_init( & argc, & argv );
   
    okno = utworz_okno();
    gtk_widget_show( okno );
   
    gtk_main();
    return 0;
}
Poprzedni dokument Następny dokument
Tworzenie GUI - menu, pola tekstowe i etykiety Kurs STC