2

我担心的是我创建了一个回调函数,Gtk_Entry当我们单击时它应该显示一个,Gtk_Button但是当我单击按钮时没有任何反应。我不明白。

文件.ads

Package Test is

    Type T_Test is record
        Conteneur : Gtk_Fixe;
        L_Entree : Gtk_Entry;
    end Record;

    Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Class);

    Package P is new Gtk.Handlers.Callback (Gtk_Button_Record);

    Use P;

end Test;

文件.adb

Package body Test is

    Procedure Initialise_Conteneur (Object : T_Test) is
    begin
        Gtk_New (Object.Conteneur);

    end Initialise_Conteneur;

    Procedure Le_Callback (Emetteur : access Gtk_Button_Record'Classs) is
        V : T_Test;

    begin
        Initialise_Conteneur (Object => V);
        Gtk_New (V.L_Entree);
        V.Conteneur.Add (V.L_Entree);

        V.L_Entree.Show;

    end Le_Callback;
end Test;

主文件

Procedure Main is
    Win : Gtk_Window;
    Button : Gtk_Button;
    Posix : T_Test;

begin
    Init;
    Initialize (object => Posix);

    1
    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_Test'Access),
                    After => true);

    Posix.Conteneur.Add (Button);
    Win.Add (Posix.Conteneur);

    Win.Show_All;
    Main;

end Main;
4

2 回答 2

3

修改后的答案。

稍微破解包 ... 以导出 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;

包体中的几个问题...

  1. Initialize 函数中的参数传递方式。
  2. 确保新的可见对象与旧的对象位于不同的位置......(注意 GTK_Fixed 是一个比其他容器更难使用的容器,就手动布局而言
  3. 回调创建一个新容器(现在其中有一个按钮)......但在容器属于某物之前,它无法显示。主窗口在此包中不直接可见,因此我将其添加到发出信号的按钮的父容器中。(有一些方法可以将用户数据传递给处理程序;您可以使用它来传递顶级窗口或其他容器)
  4. 当然我们必须显示修改,所以让我们重绘顶层窗口。

(用于修复标记问题的垃圾文本)

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;

现在它构建(将来,请让示例代码可构建!会节省大量时间),我可以看到一个按钮......

按下按钮,第二个按钮出现在其下方,因此我们知道处理程序已连接到按钮,并接收按钮按下消息。

于 2021-11-20T23:33:48.767 回答
0

这更像是某种评论,但这就是我在 vala 中的做法(使用valac --pkg=gtk+-3.0 $FILENAME.

int main (string[] args) {
    Gtk.init (ref args);
    var window = new Gtk.Window ();
    window.title = "MyWindow";
    window.destroy.connect (Gtk.main_quit);
    // Create a box, where we later add the button and then the entry
    var box = new Gtk.Box (Gtk.Orientation.VERTICAL, /*spacing*/ 2);
    var button = new Gtk.Button.with_label ("Bouton!");
    // Connect to the signal "clicked", that is executed, as soon
    // as the button is clicked by the user
    button.clicked.connect (() => { // () => {...} is your callback.
        // Add the entry to the box
        box.pack_start (new Gtk.Entry());
        // Redraw the window
        window.show_all ();
    });
    // Add the button to the box
    box.pack_start (button);
    // Add the box to the window
    window.add (box);
    // Show the main window
    window.show_all ();  
    // GTK-Mainloop
    Gtk.main ();
    return 0; 
}
于 2021-11-21T06:05:05.837 回答