我正在使用gtkada编写程序,以显示带有Text_View(在Scrolled_Window内)的窗口,该窗口将从GEntry更新。
除了滚动之外,我几乎可以按照我的意愿工作。
由于从GEntry处理了输入并将其插入到Text_View中,我希望它自动滚动,因此最新的输入在底部可见。
如果我理解正确,则在插入文本后执行Scroll_To_Iter将不起作用。需要使用一个空闲处理程序来处理滚动。
我只需要有关如何调用它的指针。
从GEntry插入文本的过程如下:
procedure Insert_Text (S_Out: String) is
Iter : Gtk_Text_Iter;
Scroll_Okay : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Insert (TextBuffer, Iter, "You entered:" & ASCII.LF);
Get_End_Iter (TextBuffer, Iter);
Insert (TextBuffer, Iter, S_Out & ASCII.LF);
Get_End_Iter (TextBuffer, Iter);
Scroll_Okay := Scroll_To_Iter
(TextView, Iter, 0.0, True, 1.0, 1.0);
end Insert_Text;
我在此处包括的Scroll_To_Iter调用只是为了说明;我知道那没用。
我在同一软件包中有一个单独的过程:
procedure Idle_Scroll (Object : access Gtk_Widget_Record'Class) is
Iter : Gtk_Text_Iter;
Scroll_Okay : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Scroll_Okay := Scroll_To_Iter
(TextView, Iter, 0.0, True, 1.0, 1.0);
end Idle_Scroll;
所以我只想知道如何设置适当的空闲处理程序。非常感谢您的帮助。
进一步回答下面的问题(谢谢),此后我一直尝试修改代码,将过程更改为函数,而且似乎朝着正确的方向发展。在尝试调用Idle_Scroll回调时,我仍然卡住,我得到错误'...在glib-main.ads中定义的预期类型“ G_Source_Func” ...发现对函数“ Idle_Scroll”的类型访问...'在读取glibmain.h中的条目后,设置传递给G_Source_Func类型的Idle_Scroll的参数,但是我似乎转了一圈。我已在此处上传到sourceforge的完整代码:https://sourceforge.net/projects/test-textview/files/
答案 0 :(得分:1)
设法使其正常工作。
更改了包test_textview_declare.ads中的声明:
package Idle_Cb is new Glib.Main.Generic_Sources (Gtk_Text_View);
Idle_Id : G_Source_Id;
test_textview_cb.adb中的Idle_Scroll函数现在为:
function Idle_Scroll (The_View : Gtk_Text_View) return Boolean is
Iter : Gtk_Text_Iter;
Scroll_Okay : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Scroll_Okay := Scroll_To_Iter
(The_View, Iter, 0.0, True, 1.0, 1.0);
return True;
end Idle_Scroll;
“返回真”是难题的最后一部分。我已经阅读了几本参考手册,但是却错过了我需要该行以使空闲函数继续运行的事实。今天下午我在程序执行时让Idle_Scroll运行,但是只有一次。返回True可以确保它被重复调用。
我之前还编辑了该行,以便在test_textview_start.adb中添加空闲函数:
Idle_Id := Idle_Cb.Idle_Add (Idle_Scroll'Access, TextView);
再次感谢您的帮助。
发言时间过早。
我的上述解决方案效果很好。将文本从GEntry输入到Text_View后,它会自动滚动到底部,但是我无法向上移动滚动条以查看较早的内容。
解决此问题的方法是将对Idle_Add的调用移至回调包test_testview.adb中,并在函数Idle_Scroll中将返回行更改为“ Return:= False;”。这样,在输入文本后,它会滚动到底部,但仍允许滚动条上下移动。
test_textview.adb的最终版本如下:
package body Test_TextView_Cb is
function Idle_Scroll (The_View : Gtk_Text_View) return Boolean is
Iter : Gtk_Text_Iter;
Success : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Success := Scroll_To_Iter (The_View, Iter, 0.0, True, 1.0, 1.0);
return False;
end Idle_Scroll;
procedure Insert_Text (OutStr: String) is
Iter : Gtk_Text_Iter;
begin
Get_End_Iter (TextBuffer, Iter);
Insert (TextBuffer, Iter, "You entered:" & ASCII.LF
& OutStr & ASCII.LF);
Idle_Id := Idle_Cb.Idle_Add (Idle_Scroll'Access, TextView);
end Insert_Text;
procedure Enter_Pressed (Self : access Gtk_Widget_Record'Class) is
Entered_Text : String := Get_Text (Cmd_Entry);
begin
Insert_Text (Entered_Text);
Set_Text (Cmd_Entry, "");
end Enter_Pressed;
procedure Main_Quit (Self : access Gtk_Widget_Record'Class) is
begin
Gtk.Main.Main_Quit;
end Main_Quit;
procedure Button_Quit (Self : access Gtk_Widget_Record'Class) is
begin
Destroy (Self);
end Button_Quit;
end Test_TextView_Cb;
答案 1 :(得分:0)
我认为您应该尝试使用 Glib.Main 包中的 Idle_Add 过程。像
procedure Insert_Text (S_Out: String) is
Iter : Gtk_Text_Iter;
Scroll_Okay : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Insert (TextBuffer, Iter, "You entered:" & ASCII.LF);
Get_End_Iter (TextBuffer, Iter);
Insert (TextBuffer, Iter, S_Out & ASCII.LF);
Get_End_Iter (TextBuffer, Iter);
GLib.Main.Idle_Add (Idle_Scroll'access);
end Insert_Text;
但是您必须将过程转换为返回布尔值的函数。 如果需要将参数传递给代码,请使用通用内部包 Generic_Sources 的实例化,以提供将通过回调传递给代码的数据结构。
请注意,我没有编译这段代码,您可能需要对它进行一些更改:)
编辑:
我忘了提到 G_Source_Func 的原型是
type G_Source_Func is access function return Boolean;
这意味着它不应具有任何参数。 所以 Idle_Scroll 应该是这样的
function Idle_Scroll return Boolean is
Iter : Gtk_Text_Iter;
Scroll_Okay : Boolean;
begin
Get_End_Iter (TextBuffer, Iter);
Scroll_Okay := Scroll_To_Iter
(TextView, Iter, 0.0, True, 1.0, 1.0);
return Scroll_Okay;
end Idle_Scroll;