0

我创建了一个程序“freedisk”来在 Gtk3 网格中显示一些数据。一个新窗口填充了一些用于布局和标签目的的框,主要内容是可更新的,填充网格,它本身在一个 VBox 中。

数据显示工作正常;问题在于更新过程。我打算销毁网格中的子小部件,并使用新数据重新创建它们。

存在一个应该触发更新的按钮,当单击它时,它将通过处理程序传递 VBox 的名称(在程序“Content_Box”中调用),然后该处理程序运行适当的子程序来销毁 Content_Box 子项并重新创建它们。

简化代码如下(先处理程序包):

Freedisk_Cb.ads

package Freedisk_Cb is


   package User_Callback is new Gtk.Handlers.User_Callback
     (Gtk_Widget_Record, Gtk_Box);

   procedure Refresh_Clicked
     (Self : access Gtk_Widget_Record'Class;
      Data : in out Gtk_Box);


end Freedisk_Cb;

Freedisk_Cb.adb

package body Freedisk_Cb is


   procedure Refresh_Clicked
     (Self : access Gtk_Widget_Record'Class;
      Data : in out Gtk_Box)
   is
      begin
         Make_Table (Data);
   end Refresh_Clicked;


end Freedisk_Cb;

Make_Table 是计算和显示数据的子程序;我暂时把它放在一边,尽量保持简短。

主程序代码(再次被大大简化)是:

freedisk.adb

   Gtk_New (Win);

   Gtk_New_VBox (Content_Box, False, 0);

   Gtk_New (Refresh_Button, "Refresh");

   User_Callback.Object_Connect
     (Refresh_Button, "clicked",
      User_Callback.To_Marshaller (Refresh_Clicked'Access),
      Slot_Object => Win, User_Data => Content_Box);

因此,当我尝试构建它时,出现以下错误:

freedisk.adb:103:20:没有候选解释与实际情况匹配:
freedisk.adb:103:51:预期类型“处理程序”定义在 gtk-marshallers.ads:546,实例在 gtk-handlers.ads:1164,实例在freedisk_cb.ads:13
freedisk.adb:103:51: 在 gtk-handlers.ads:1205 调用“To_Marshaller”时,发现类型访问在第 103 行
freedisk.adb:103:51: ==> 中定义的过程“Refresh_Process” , freedisk_cb.ads:13
freedisk.adb:103:51: ==> 调用 gtk-handlers.ads:1200 上的“To_Marshaller”实例, freedisk_cb.ads:13
freedisk.adb:103:51: = => 在 gtk-handlers.ads:1195 调用“To_Marshaller”,freedisk_cb.ads:13 的实例

等等等等

如果传递给回调的 VBox“数据”不是输入输出变量,我不会遇到这个问题,但这种方式并没有多大用处。显然缺少一些基本的东西。

我查看了 Gtkada 文档http://docs.adacore.com/live/wave/gtkada/html/gtkada_ug/signals.html的信号页面中的示例 - 提到的示例列出了它们的代码在一个目录examples/user_data中,不幸的是我无法找到(我下载了Gtkada的二进制和源代码分发)。

提前致谢。任何帮助表示赞赏。

我现在在这里上传了完整的代码:https ://sourceforge.net/projects/tx82/files/

可以下载单个文件或完整的压缩包。

它是在 Slackware 14.2 x64 上使用 2016 GPL Gnat、Gprbuild 和 Gtkada 构建的。

4

1 回答 1

1

错误消息说它需要一个类型Handler,但找到了对过程的访问Refresh_Process(尽管根据您提供的代码,我希望编译器找到Refresh_Clicked?),这意味着参数配置文件不兼容。

查看您提供的链接中的示例,回调期望Data为 mode in。尝试将您的回调更改为

   procedure Refresh_Clicked
     (Self : access Gtk_Widget_Record'Class;
      Data : in Gtk_Box);
于 2017-11-28T07:50:15.800 回答