How do I change the text of a label after clicking a button using GtkAda

589 Views Asked by At

I have this code which has 1 label and 3 buttons. What I want is to change the text of the label if I press a certain button. If I click the first button the label text will change to "Hello" and if I click the second button the label text will change to "World" and lastly if I click the third button the label text should become "Hello World".

with Gdk.Event;       use Gdk.Event;

with Gtk.Box;         use Gtk.Box;
with Gtk.Label;       use Gtk.Label;
with Gtk.Widget;      use Gtk.Widget;
with Gtk.Main;
with Gtk.Window;      use Gtk.Window;
with Gtk.Button;      use Gtk.Button;
with Gtk.Grid;        use Gtk.Grid;

procedure Main is

   Win   : Gtk_Window;
   Label : Gtk_Label;
   Box   : Gtk_Vbox;
   Button: Gtk_Button;
   Button2: Gtk_Button;
   Button3: Gtk_Button;
   Grid  : Gtk_Grid;

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean;

   ---------------------
   -- Delete_Event_Cb --
   ---------------------

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean
   is
      pragma Unreferenced (Self, Event);
   begin
      Gtk.Main.Main_Quit;
      return True;
   end Delete_Event_Cb;

begin
   --  Initialize GtkAda.
   Gtk.Main.Init;

   --  Create a window with a size of 100x120
   Gtk_New (Win);
   Win.Set_Default_Size (100, 120);

   --  Create a box to organize vertically the contents of the window
   Gtk_New_Vbox (Box);
   Win.Add (Box);


   --  Add a label
   Gtk_New (Label, "Hello world.");
   Box.Add (Label);
 
   -- Add a Grid
   Gtk_New (Grid);
   Box.Add (Grid);
    
   -- Add the first button to the grid 
   Gtk_New (Button, "Hello");
   Grid.Attach (Button, 0, 0, 1, 1);

   -- Add Second button to the grid
   Gtk_New (Button2, "World");
   Grid.Attach (Button2, 1, 0, 1, 1);

   -- Add the third button to the grid
   Gtk_New (Button3, "Hello World!");
   Grid.Attach (Button3, 0, 1, 2, 1);

   -- Stop the Gtk process when closing the window
   Win.On_Delete_Event (Delete_Event_Cb'Unrestricted_Access);

   --  Show the window and present it
   Win.Show_All;
   Win.Present;

   --  Start the Gtk+ main loop
   Gtk.Main.Main;
end Main;

What should I add to make that happen?

2

There are 2 best solutions below

1
On BEST ANSWER

@thindil gave me an idea on how to change the label text using the set_text procedure, however whenever I run his code this message always shows: "subprogram must not be deeper than access type".

Instead of getting a nested procedure, I created a new package. Here's the updated code:

main.adb

with Gdk.Event;       use Gdk.Event;

with Gtk.Box;         use Gtk.Box;
with Gtk.Label;       use Gtk.Label;
with Gtk.Widget;      use Gtk.Widget;
with Gtk.Main;
with Gtk.Window;      use Gtk.Window;
with Gtk.Button;      use Gtk.Button;


with button_click;    use button_click;
procedure Main is

   Win   : Gtk_Window;
   Box   : Gtk_Vbox;
   Box2  : Gtk_Vbox;
   Box3  : Gtk_Hbox;
   Box4  : Gtk_Hbox;
   Box5  : Gtk_Hbox;
   

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean;

   ---------------------
   -- Delete_Event_Cb --
   ---------------------

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean
   is
      pragma Unreferenced (Self, Event);
   begin
      Gtk.Main.Main_Quit;
      return True;
   end Delete_Event_Cb;
   
   

begin
   --  Initialize GtkAda.
   Gtk.Main.Init;

   --  Create a window with a size of 400x400
   Gtk_New (Win);
   Win.Set_Default_Size (400, 400);

   --  Create a box to organize vertically the contents of the window
   Gtk_New_Vbox (Box);
   Win.Add (Box);

   --  Add a label inside Vbox Box
   Gtk_New (button_click.Label, "Try Pressing the buttons :)");
   Box.Add (button_click.Label);

   -- Adding Vbox Box2 inside Box
   Gtk_New_Vbox (Box2);
   Box.Add (Box2);

   -- Adding Hbox Box3 inside Box2
   Gtk_New_Hbox (Box3);
   Box2.Add (Box3);

   -- Adding Hbox Box4 inside Vbox Box3
   Gtk_New_Hbox (Box4);
   Box3.Add (Box4);

   -- Adding Hbox Box5 inside Vbox Box3
   Gtk_New_Hbox (Box5);
   Box3.Add (Box5);

   -- Placing Button inside Hbox Box3
   Gtk_New (button_click.Button, "Hello");
   Box4.Add (button_click.Button);
   On_Clicked(button_click.Button, button_clicked'Access);

   -- Placing Button2 inside Hbox Box4
   Gtk_New (button_click.Button2, "World");
   Box5.Add (button_click.Button2);
   On_Clicked(button_click.Button2, button_clicked'Access);
   
   -- Placing Button3 inside Vbox Box2
   Gtk_New (button_click.Button3, "Hello World");
   Box2.Add (button_click.Button3);
   On_Clicked(button_click.Button3, button_clicked'Access);


   -- Stop the Gtk process when closing the window
   Win.On_Delete_Event (Delete_Event_Cb'Unrestricted_Access);

   --  Show the window and present it
   Win.Show_All;
   Win.Present;

   --  Start the Gtk+ main loop
   Gtk.Main.Main;
end Main;

button_click.ads

with Gtk.Button;  use Gtk.Button;
with Gtk.Label;       use Gtk.Label;

package button_click is
   
   Button: Gtk_Button;
   Button2: Gtk_Button;
   Button3: Gtk_Button;
   Label : Gtk_Label;
   procedure button_clicked (Self : access Gtk_Button_Record'Class);
end button_click;

button_click.adb

with Gtk.Button;  use Gtk.Button;
with Gtk.Label;       use Gtk.Label;

package body button_click is
  
   procedure button_clicked (Self : access Gtk_Button_Record'Class) is
   begin
      if Self = Button then
         Set_Text(Label, "Hello");
      elsif Self = Button2 then
         Set_Text(Label, "World");
      else
         Set_Text(Label, "Hello World");
      end if;
   end button_clicked;

end button_click;
0
On

You have to add a callback to buttons to modify the label, in a very similar way like it is done in GTK. I didn't use GTKAda by some time, but it should work:

with Gdk.Event;       use Gdk.Event;

with Gtk.Box;         use Gtk.Box;
with Gtk.Label;       use Gtk.Label;
with Gtk.Widget;      use Gtk.Widget;
with Gtk.Main;
with Gtk.Window;      use Gtk.Window;
with Gtk.Button;      use Gtk.Button;
with Gtk.Grid;        use Gtk.Grid;

procedure Main is

   Win   : Gtk_Window;
   Label : Gtk_Label;
   Box   : Gtk_Vbox;
   Button: Gtk_Button;
   Button2: Gtk_Button;
   Button3: Gtk_Button;
   Grid  : Gtk_Grid;

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean;

   ---------------------
   -- Delete_Event_Cb --
   ---------------------

   function Delete_Event_Cb
     (Self  : access Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event)
      return Boolean
   is
      pragma Unreferenced (Self, Event);
   begin
      Gtk.Main.Main_Quit;
      return True;
   end Delete_Event_Cb;

   -- Callback to update label when buttons were clicked
   procedure Update_Label(Self : access Gtk_Button_Record'Class) is
   begin
      if Self = Button then
         Set_Text(Label, "Hello");
      elsif Self = Button2 then
         Set_Text(Label, "World");
      else
         Set_Text(Label, "Hello World");
      end if;
   end Update_Label;

begin
   --  Initialize GtkAda.
   Gtk.Main.Init;

   --  Create a window with a size of 100x120
   Gtk_New (Win);
   Win.Set_Default_Size (100, 120);

   --  Create a box to organize vertically the contents of the window
   Gtk_New_Vbox (Box);
   Win.Add (Box);


   --  Add a label
   Gtk_New (Label, "Hello world.");
   Box.Add (Label);
 
   -- Add a Grid
   Gtk_New (Grid);
   Box.Add (Grid);
    
   -- Add the first button to the grid 
   Gtk_New (Button, "Hello");
   -- Attach the callback to the button's event On_Click
   On_Clicked(Button, Update_Label'Access);
   Grid.Attach (Button, 0, 0, 1, 1);

   -- Add Second button to the grid
   Gtk_New (Button2, "World");
   -- Attach the callback to the second button's event On_Click
   On_Clicked(Button2, Update_Label'Access);
   Grid.Attach (Button2, 1, 0, 1, 1);

   -- Add the third button to the grid
   Gtk_New (Button3, "Hello World!");
   -- Attach the callback to the third button's event On_Click
   On_Clicked(Button3, Update_Label'Access);
   Grid.Attach (Button3, 0, 1, 2, 1);

   -- Stop the Gtk process when closing the window
   Win.On_Delete_Event (Delete_Event_Cb'Unrestricted_Access);

   --  Show the window and present it
   Win.Show_All;
   Win.Present;

   --  Start the Gtk+ main loop
   Gtk.Main.Main;
end Main;