You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GtkAda中点击Gtk_Button触发回调显示Gtk_Entry无响应问题求助

问题核心原因

代码存在以下几处关键错误:

  • 回调函数Le_Callback中声明的V : T_Test是局部栈变量,其内部创建的Conteneur容器从未被添加到主窗口的组件渲染树中,回调执行结束后该局部变量会被直接回收,关联的Entry自然无法显示
  • Initialise_Conteneur过程的Object参数是传值模式,过程内对Object.Conteneur的Gtk_New操作只会修改参数副本,不会生效到实参本身,需要改为in out传参模式
  • 主程序Main.adb的信号连接代码中,传入的回调函数名错误:实际定义的回调是Le_Callback,代码中写的是不存在的Le_Test'Access,属于编译级错误
  • 现有回调逻辑重复创建了Gtk_Fixe容器,而主窗口中已经绑定了Posix.Conteneur实例,无需重复创建容器,直接将Entry添加到已挂载的Posix.Conteneur即可

修正后代码

File.ads

Package Test is
    Type T_Test is record
        Conteneur : Gtk_Fixe;
        L_Entree : Gtk_Entry;
    end Record;
    -- 回调增加用户数据参数,接收外部传入的T_Test实例
    Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Class; User_Data : T_Test);
    -- 使用带用户数据的回调实例化包
    Package P is new Gtk.Handlers.User_Callback (Gtk_Button_Record, T_Test);
    Use P;
    -- 参数改为in out模式
    Procedure Initialise_Conteneur (Object : in out T_Test);
end Test;

File.adb

Package body Test is
    Procedure Initialise_Conteneur (Object : in out T_Test) is
    begin
        Gtk_New (Object.Conteneur);
    end Initialise_Conteneur;
    Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Class; User_Data : T_Test) is
    begin
        -- 直接操作传入的已挂载容器,无需重复创建Conteneur
        Gtk_New (User_Data.L_Entree);
        User_Data.Conteneur.Add (User_Data.L_Entree);
        -- 设置Entry的显示位置,避免和按钮重叠被遮挡
        User_Data.Conteneur.Put (User_Data.L_Entree, 10, 50);
        User_Data.L_Entree.Show;
    end Le_Callback;
end Test;

Main.adb

Procedure Main is
    Win : Gtk_Window;
    Button : Gtk_Button;
    Posix : T_Test;
begin
    Init;
    Initialise_Conteneur (Posix); -- 调用修正后的初始化方法
    Gtk_New (Win);
    Win.Set_Default_Size (600,400);
    Gtk_New (Button,"Bouton");
    -- 绑定信号时传入Posix作为用户数据,回调函数名修正为Le_Callback
    Test.P.Connect (Widget => Button,
                    Name => Signal_Clicked,
                    Marsh => P.To_Marshaller (Le_Callback'Access),
                    User_Data => Posix,
                    After => true);
    Posix.Conteneur.Put (Button, 10, 10);
    Posix.Conteneur.Add (Button);
    Win.Add (Posix.Conteneur);
    Win.Show_All;
    Main;
end Main;

内容的提问来源于stack exchange,提问作者Danielle Mandi Mayagha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 20:54:02