修改后的答案。
稍微破解包 ... 以导出 Main 中调用的 Initialize 方法。(我还添加了一个按钮而不是一个条目,以使我的生活更简单)
with Gtk; use Gtk;
with Gtk.Button; use Gtk.Button;
with Gtk.Handlers; use Gtk.Handlers;
with Gtk.Fixed; use Gtk.Fixed;
Package Test is
Type T_Test is record
Conteneur : Gtk_Fixed;
Bouton : Gtk_Button;
end Record;
procedure Initialize (Object : out T_Test);
Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Class);
Package P is new Gtk.Handlers.Callback (Gtk_Button_Record);
Use P;
end Test;
包体中的几个问题...
- Initialize 函数中的参数传递方式。
- 确保新的可见对象与旧的对象位于不同的位置......(注意 GTK_Fixed 是一个比其他容器更难使用的容器,就手动布局而言
- 回调创建一个新容器(现在其中有一个按钮)......但在容器属于某物之前,它无法显示。主窗口在此包中不直接可见,因此我将其添加到发出信号的按钮的父容器中。(有一些方法可以将用户数据传递给处理程序;您可以使用它来传递顶级窗口或其他容器)
- 当然我们必须显示修改,所以让我们重绘顶层窗口。
(用于修复标记问题的垃圾文本)
Package body Test is
Procedure Initialise_Conteneur (Object : out T_Test) is
begin
Gtk_New (Object.Conteneur);
end Initialise_Conteneur;
procedure Initialize (Object : out T_Test) renames Initialise_Conteneur;
Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Class) is
V : T_Test;
begin
Initialise_Conteneur (Object => V);
Gtk_New (V.Bouton,"Autre_Bouton");
V.Conteneur.Add (V.Bouton);
-- make sure it doesn't sit on the other button...
-- Using gtk.fixed is hard work compared to newer containers
V.Conteneur.Move(V.Bouton,0,35);
-- Add our new GTK_Fixed container to the outer one
-- note Get_Parent returns a GTK_Widget'Class so we must
-- view convert to a GTK_Container or GTK_Fixed to see the Add method
Gtk_Fixed(Emetteur.Get_Parent).Add(V.Conteneur);
-- And re-display the top level window
Emetteur.Get_Toplevel.Show_All;
end Le_Callback;
end Test;
和主程序(连接 Le_Callback,而不是不存在的 Le_Test)......
with Gtk.Button; use Gtk.Button;
with Gtk.Window; use Gtk.Window;
with Gtk.Main;
with test; use test;
Procedure Main is
Win : Gtk_Window;
Button : Gtk_Button;
Posix : T_Test;
begin
Gtk.Main.Init;
Initialize (object => Posix);
Gtk_New (Win);
Win.Set_Default_Size (600,400);
Gtk_New (Button,"Bouton");
Test.P.Connect (Widget => Button,
Name => Signal_Clicked,
Marsh => P.To_Marshaller (Le_Callback'Access),
After => true);
Posix.Conteneur.Add (Button);
Win.Add (Posix.Conteneur);
Win.Show_All;
GTK.Main.Main;
end Main;
和我的 GPR 文件。
with "gtkada";
-- with "gtkada_gl";
project Test is
for Main use ("main.adb");
for Source_Dirs use (".");
for Object_Dir use "obj";
for Exec_Dir use ".";
package Compiler is
for Default_Switches ("Ada") use ("-g", "-O1", "-gnatafo");
end Compiler;
package Binder is
for Default_Switches ("Ada") use ("-E");
end Binder;
package Linker is
-- for Default_Switches ("Ada") use ("-lgtkglada");
end Linker;
end Test;
现在它构建(将来,请让示例代码可构建!会节省大量时间),我可以看到一个按钮......
按下按钮,第二个按钮出现在其下方,因此我们知道处理程序已连接到按钮,并接收按钮按下消息。