如何将回调函数连接到其信号

发布于 2025-01-10 05:42:49 字数 2975 浏览 0 评论 0原文

我创建了两个显示 Gtk_Radio_Button 的按钮和一个显示 GtK_label 的按钮,但是当我单击按钮时没有任何反应。我不明白为什么它不起作用,但代码编译并运行时没有发现任何错误。

main_Program.adb

With Gtk.Window;     Use Gtk.Window;
With Gtk.Button;     Use Gtk.Button;
With Gtk.Grid;       Use Gtk.Grid;
With file;           Use file;

Procedure main_program is
   
   Bouton : Gtk_Button;
   Bouton2 : Gtk_Button;
   Win : Gtk_Window;
   Test : Test_Record;
   
begin
   Gtk.Main.Init;
   
   Init_Grid (Container => Test);
   
   Gtk_New (Win);
   
   Win.Add (Test.Grid);
   
   Win.Set_Default_Size (Width  => 600,
                         Height => 400);
   
   Gtk_New (Bouton,Label => "Bouton");
   Test.Grid.Attach (Bouton,0,0);
   
   P.Connect (Widget => Bouton,
              Name   => Signal_Clicked,
              Marsh  => Test2.P.To_Marshaller (Init_Button'Access),
              After  => False);
   
   Gtk_New (Bouton2,Label => "Bouton2");
   Test.Grid.Attach (Bouton2,50,4);
   
   P.Connect (Widget => Bouton2,
              Name   => Signal_Clicked,
              Marsh  => Test2.P.To_Marshaller (Init_Text'Access),
              After  => False);
   
   Win.Show_All;
   
   Main;   
end Main_Program;

file.ads

With Gtk.Label;          Use Gtk.Label;
With Gtk.Radio_Button;   Use Gtk.Radio_Button;
With Gtk.Grid;           Use Gtk.Grid;
With Gtk.Handlers;

Package file is
   
   type Test_Record is record
      
      Text : Gtk_Label;
      Grid : Gtk_Grid;
      Button_Radio : Gtk_Radio_Button;
      
   end record;
   
   Procedure Init_Text ( Self : access Gtk_Widget_Record'Class );

   --   Callback for create the text
   
   Procedure Init_Button (Self : access Gtk_Widget_Record'Class );

   --   Callback for Initialize the Radio Button;
   
   Procedure Init_Grid (Container : out Test_Record);

   --   Initialize the Gtk.Grid.Gtk_Grid
   
   Package P is new Gtk.Handlers.Callback (Gtk_Widget_Record);
   
   Use P;
   
end file;

file.adb

With file;        Use file;

Package body file is
   
   Procedure Init_Grid ( Container : out Test_Record ) is
   begin
      
      Gtk_New (Container.Grid);
      
   end Init_Grid;
   
   Procedure Init_Button ( Self : access Gtk_Widget_Record'Class ) is
      
      V : Test_Record;
   begin
      Init_Grid (Container => V);
      
      Gtk_New (V.Button_Radio,
               Group => null,
               Label => "Button Radio");
      
      V.Grid.Attach (V.Button_Radio,0,50);
      
      V.Grid.Show;
      
   end Init_Button;
   
   Procedure Init_Text (Self : access Gtk_Widget_Record'Class) is
      
      V : Test_Record;
   begin
      Init_Grid (Container => V);
      
      Gtk_New (V.Text);
      
      V.Text.Set_Label ("Hello,World");
      
      V.Grid.Attach (V.Text,150,0);
      
      V.Grid.Show;
      
   end Init_Text;
end file;

我希望当我单击第一个按钮时,它会显示一个单选按钮,当我单击第二个按钮时,它会显示一个标签。

i created two buttons a that display a Gtk_Radio_Button and a button that display a GtK_label but when i click on buttons nothing happens. I don't understand why it doesn't work yet the code compiles and runs without finding any error.

main_Program.adb

With Gtk.Window;     Use Gtk.Window;
With Gtk.Button;     Use Gtk.Button;
With Gtk.Grid;       Use Gtk.Grid;
With file;           Use file;

Procedure main_program is
   
   Bouton : Gtk_Button;
   Bouton2 : Gtk_Button;
   Win : Gtk_Window;
   Test : Test_Record;
   
begin
   Gtk.Main.Init;
   
   Init_Grid (Container => Test);
   
   Gtk_New (Win);
   
   Win.Add (Test.Grid);
   
   Win.Set_Default_Size (Width  => 600,
                         Height => 400);
   
   Gtk_New (Bouton,Label => "Bouton");
   Test.Grid.Attach (Bouton,0,0);
   
   P.Connect (Widget => Bouton,
              Name   => Signal_Clicked,
              Marsh  => Test2.P.To_Marshaller (Init_Button'Access),
              After  => False);
   
   Gtk_New (Bouton2,Label => "Bouton2");
   Test.Grid.Attach (Bouton2,50,4);
   
   P.Connect (Widget => Bouton2,
              Name   => Signal_Clicked,
              Marsh  => Test2.P.To_Marshaller (Init_Text'Access),
              After  => False);
   
   Win.Show_All;
   
   Main;   
end Main_Program;

file.ads

With Gtk.Label;          Use Gtk.Label;
With Gtk.Radio_Button;   Use Gtk.Radio_Button;
With Gtk.Grid;           Use Gtk.Grid;
With Gtk.Handlers;

Package file is
   
   type Test_Record is record
      
      Text : Gtk_Label;
      Grid : Gtk_Grid;
      Button_Radio : Gtk_Radio_Button;
      
   end record;
   
   Procedure Init_Text ( Self : access Gtk_Widget_Record'Class );

   --   Callback for create the text
   
   Procedure Init_Button (Self : access Gtk_Widget_Record'Class );

   --   Callback for Initialize the Radio Button;
   
   Procedure Init_Grid (Container : out Test_Record);

   --   Initialize the Gtk.Grid.Gtk_Grid
   
   Package P is new Gtk.Handlers.Callback (Gtk_Widget_Record);
   
   Use P;
   
end file;

file.adb

With file;        Use file;

Package body file is
   
   Procedure Init_Grid ( Container : out Test_Record ) is
   begin
      
      Gtk_New (Container.Grid);
      
   end Init_Grid;
   
   Procedure Init_Button ( Self : access Gtk_Widget_Record'Class ) is
      
      V : Test_Record;
   begin
      Init_Grid (Container => V);
      
      Gtk_New (V.Button_Radio,
               Group => null,
               Label => "Button Radio");
      
      V.Grid.Attach (V.Button_Radio,0,50);
      
      V.Grid.Show;
      
   end Init_Button;
   
   Procedure Init_Text (Self : access Gtk_Widget_Record'Class) is
      
      V : Test_Record;
   begin
      Init_Grid (Container => V);
      
      Gtk_New (V.Text);
      
      V.Text.Set_Label ("Hello,World");
      
      V.Grid.Attach (V.Text,150,0);
      
      V.Grid.Show;
      
   end Init_Text;
end file;

I want that when I click on the first button it shows me a radio button and when I click on the second button it shows me a label.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

洒一地阳光 2025-01-17 05:42:49

我会考虑不创建/销毁标签和单选按钮,而只是切换它们的可见性。此外,我还建议从 GTK 窗口类型派生主窗口,并始终在请求时正确终止应用程序(请参阅下面示例中的 Destroy_Event_Callback)。

app.ads

package App is

end App;

app-main_window.ads

with Gtk.Window;       use Gtk.Window;
with Gtk.Grid;         use Gtk.Grid;
with Gtk.Button;       use Gtk.Button;
with Gtk.Check_Button; use Gtk.Check_Button;
with Gtk.Label;        use Gtk.Label;  

package App.Main_Window is

   type App_Main_Window_Record is new Gtk_Window_Record with private;
   type App_Main_Window is access all App_Main_Window_Record'Class;

   ------------------
   -- Constructors --
   ------------------

   procedure Gtk_New
     (Main_Window : out App_Main_Window);
   procedure Initialize
     (Main_Window : not null access App_Main_Window_Record'Class);

private
   
   Window_Width  : constant := 300;
   Window_Height : constant := 100;     
   
   type App_Main_Window_Record is
     new Gtk.Window.Gtk_Window_Record with
      record
         Grid         : Gtk_Grid;        
         Button_1     : Gtk_Button;
         Button_2     : Gtk_Button;
         Check_Button : Gtk_Check_Button;
         Label        : Gtk_Label;
      end record;

end App.Main_Window;

app-main_window.adb

with Gtk.Main;
with Gtk.Widget;
with Gtk.Window;
with Gdk.Event;

package body App.Main_Window is

   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);

   function On_Button_1_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean;
   
   function On_Button_2_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean;

   -------------
   -- Gtk_New --
   -------------

   procedure Gtk_New (Main_Window : out App_Main_Window) is
   begin
      Main_Window := new App_Main_Window_Record;
      App.Main_Window.Initialize (Main_Window);
   end Gtk_New;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize
     (Main_Window : not null access App_Main_Window_Record'Class)
   is
   begin

      --  Initialize and setup the window.
      Gtk.Window.Initialize (Main_Window);
      
      Main_Window.Set_Title ("Demo Window");
      Main_Window.Set_Size_Request (Window_Width, Window_Height);
      Main_Window.Set_Resizable (False);

      --  Attach callback: properly end the GTK application when requested.
      Main_Window.On_Destroy
        (Call => Destroy_Event_Callback'Access);

      --  Add a grid.
      Gtk_New (Main_Window.Grid);
      Main_Window.Grid.Set_Hexpand (True);
      Main_Window.Grid.Set_Vexpand (True);
      Main_Window.Grid.Set_Column_Homogeneous (True);
      Main_Window.Grid.Set_Row_Homogeneous (True);
      
      Main_Window.Add (Main_Window.Grid);
      
      --  Create the two buttons.
      Gtk_New (Main_Window.Button_1, Label => "Button 1");
      Gtk_New (Main_Window.Button_2, Label => "Button 2");
      
      --  Insert both buttons into the grid.
      --
      --            +------+------+
      --            |      |      | 
      --            +------+------+
      --  (0,1) --> | XXXX | XXXX | <-- (1,1)
      --            +------+------+
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Button_1,
         Left  => 0,
         Top   => 1);
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Button_2,
         Left  => 1,
         Top   => 1);
      
      --  Attach "button pressed" callbacks.
      Main_Window.Button_1.On_Button_Press_Event
        (Call => On_Button_1_Pressed_Callback'Access);
      Main_Window.Button_2.On_Button_Press_Event
        (Call => On_Button_2_Pressed_Callback'Access);
      
      --  Create new label and check button.
      Gtk_New (Main_Window.Label, Str => "Hello World!");
      Gtk_New (Main_Window.Check_Button, Label => "A Check Button");      
      
      --  Insert both into the grid.
      --
      --            +------+------+
      --  (0,0) --> | XXXXXXXXXXX |   Width: 2 columns
      --            +------+------+
      --            |      |      |
      --            +------+------+
            
      Main_Window.Grid.Attach
        (Child => Main_Window.Label,
         Left  => 0,
         Top   => 0,
         Width => 2);
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Check_Button,
         Left  => 0,
         Top   => 0,
         Width => 2);
      
      --  Show everything except the check button.
      Main_Window.Show;
      Main_Window.Grid.Show;
      Main_Window.Button_1.Show;
      Main_Window.Button_2.Show;
      Main_Window.Label.Show;

   end Initialize;

   ----------------------------
   -- Destroy_Event_Callback --
   ----------------------------

   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
   is
   begin
      Gtk.Main.Main_Quit;
   end Destroy_Event_Callback;

   ----------------------------------
   -- On_Button_1_Pressed_Callback --
   ----------------------------------

   function On_Button_1_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean
   is
      --                (parent)      (parent)
      --  Button (Self) -------> Grid -------> Window
      
      Grid   : Gtk_Grid := Gtk_Grid (Self.Get_Parent);
      Window : App_Main_Window := App_Main_Window (Grid.Get_Parent);
      
   begin
      --  Just toggle visibility.
      Window.Label.Set_Visible (False);
      Window.Check_Button.Set_Visible (True);
      return True;   --  GDK_EVENT_STOP, do not propagate event to parent.

   end On_Button_1_Pressed_Callback;

   ----------------------------------
   -- On_Button_2_Pressed_Callback --
   ----------------------------------

   function On_Button_2_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean
   is
      Grid   : Gtk_Grid := Gtk_Grid (Self.Get_Parent);
      Window : App_Main_Window := App_Main_Window (Grid.Get_Parent);

   begin
      Window.Label.Set_Visible (True);
      Window.Check_Button.Set_Visible (False);
      return True;   --  GDK_EVENT_STOP, do not propagate event to parent.

   end On_Button_2_Pressed_Callback;   
   
end App.Main_Window;

ma​​in.adb

with Gtk.Main;
with App.Main_Window;

procedure Main is
   use App.Main_Window;
   Main_Window : App_Main_Window;
begin
   Gtk.Main.Init;
   Gtk_New (Main_Window);
   Gtk.Main.Main;
end Main;

I would consider to not create/destroy the label and radio button, but just toggle their visibility instead. Furthermore, I would also recommend to derive the main window from the GTK window type and always properly terminate the application when requested (see Destroy_Event_Callback in the example below).

app.ads

package App is

end App;

app-main_window.ads

with Gtk.Window;       use Gtk.Window;
with Gtk.Grid;         use Gtk.Grid;
with Gtk.Button;       use Gtk.Button;
with Gtk.Check_Button; use Gtk.Check_Button;
with Gtk.Label;        use Gtk.Label;  

package App.Main_Window is

   type App_Main_Window_Record is new Gtk_Window_Record with private;
   type App_Main_Window is access all App_Main_Window_Record'Class;

   ------------------
   -- Constructors --
   ------------------

   procedure Gtk_New
     (Main_Window : out App_Main_Window);
   procedure Initialize
     (Main_Window : not null access App_Main_Window_Record'Class);

private
   
   Window_Width  : constant := 300;
   Window_Height : constant := 100;     
   
   type App_Main_Window_Record is
     new Gtk.Window.Gtk_Window_Record with
      record
         Grid         : Gtk_Grid;        
         Button_1     : Gtk_Button;
         Button_2     : Gtk_Button;
         Check_Button : Gtk_Check_Button;
         Label        : Gtk_Label;
      end record;

end App.Main_Window;

app-main_window.adb

with Gtk.Main;
with Gtk.Widget;
with Gtk.Window;
with Gdk.Event;

package body App.Main_Window is

   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);

   function On_Button_1_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean;
   
   function On_Button_2_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean;

   -------------
   -- Gtk_New --
   -------------

   procedure Gtk_New (Main_Window : out App_Main_Window) is
   begin
      Main_Window := new App_Main_Window_Record;
      App.Main_Window.Initialize (Main_Window);
   end Gtk_New;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize
     (Main_Window : not null access App_Main_Window_Record'Class)
   is
   begin

      --  Initialize and setup the window.
      Gtk.Window.Initialize (Main_Window);
      
      Main_Window.Set_Title ("Demo Window");
      Main_Window.Set_Size_Request (Window_Width, Window_Height);
      Main_Window.Set_Resizable (False);

      --  Attach callback: properly end the GTK application when requested.
      Main_Window.On_Destroy
        (Call => Destroy_Event_Callback'Access);

      --  Add a grid.
      Gtk_New (Main_Window.Grid);
      Main_Window.Grid.Set_Hexpand (True);
      Main_Window.Grid.Set_Vexpand (True);
      Main_Window.Grid.Set_Column_Homogeneous (True);
      Main_Window.Grid.Set_Row_Homogeneous (True);
      
      Main_Window.Add (Main_Window.Grid);
      
      --  Create the two buttons.
      Gtk_New (Main_Window.Button_1, Label => "Button 1");
      Gtk_New (Main_Window.Button_2, Label => "Button 2");
      
      --  Insert both buttons into the grid.
      --
      --            +------+------+
      --            |      |      | 
      --            +------+------+
      --  (0,1) --> | XXXX | XXXX | <-- (1,1)
      --            +------+------+
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Button_1,
         Left  => 0,
         Top   => 1);
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Button_2,
         Left  => 1,
         Top   => 1);
      
      --  Attach "button pressed" callbacks.
      Main_Window.Button_1.On_Button_Press_Event
        (Call => On_Button_1_Pressed_Callback'Access);
      Main_Window.Button_2.On_Button_Press_Event
        (Call => On_Button_2_Pressed_Callback'Access);
      
      --  Create new label and check button.
      Gtk_New (Main_Window.Label, Str => "Hello World!");
      Gtk_New (Main_Window.Check_Button, Label => "A Check Button");      
      
      --  Insert both into the grid.
      --
      --            +------+------+
      --  (0,0) --> | XXXXXXXXXXX |   Width: 2 columns
      --            +------+------+
      --            |      |      |
      --            +------+------+
            
      Main_Window.Grid.Attach
        (Child => Main_Window.Label,
         Left  => 0,
         Top   => 0,
         Width => 2);
      
      Main_Window.Grid.Attach
        (Child => Main_Window.Check_Button,
         Left  => 0,
         Top   => 0,
         Width => 2);
      
      --  Show everything except the check button.
      Main_Window.Show;
      Main_Window.Grid.Show;
      Main_Window.Button_1.Show;
      Main_Window.Button_2.Show;
      Main_Window.Label.Show;

   end Initialize;

   ----------------------------
   -- Destroy_Event_Callback --
   ----------------------------

   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
   is
   begin
      Gtk.Main.Main_Quit;
   end Destroy_Event_Callback;

   ----------------------------------
   -- On_Button_1_Pressed_Callback --
   ----------------------------------

   function On_Button_1_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean
   is
      --                (parent)      (parent)
      --  Button (Self) -------> Grid -------> Window
      
      Grid   : Gtk_Grid := Gtk_Grid (Self.Get_Parent);
      Window : App_Main_Window := App_Main_Window (Grid.Get_Parent);
      
   begin
      --  Just toggle visibility.
      Window.Label.Set_Visible (False);
      Window.Check_Button.Set_Visible (True);
      return True;   --  GDK_EVENT_STOP, do not propagate event to parent.

   end On_Button_1_Pressed_Callback;

   ----------------------------------
   -- On_Button_2_Pressed_Callback --
   ----------------------------------

   function On_Button_2_Pressed_Callback
     (Self  : access Gtk.Widget.Gtk_Widget_Record'Class;
      Event : Gdk.Event.Gdk_Event_Button) return Boolean
   is
      Grid   : Gtk_Grid := Gtk_Grid (Self.Get_Parent);
      Window : App_Main_Window := App_Main_Window (Grid.Get_Parent);

   begin
      Window.Label.Set_Visible (True);
      Window.Check_Button.Set_Visible (False);
      return True;   --  GDK_EVENT_STOP, do not propagate event to parent.

   end On_Button_2_Pressed_Callback;   
   
end App.Main_Window;

main.adb

with Gtk.Main;
with App.Main_Window;

procedure Main is
   use App.Main_Window;
   Main_Window : App_Main_Window;
begin
   Gtk.Main.Init;
   Gtk_New (Main_Window);
   Gtk.Main.Main;
end Main;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文