我创建了一个程序“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 构建的。