使用scroll_to_iter自动滚动gtkada中的Text_View

时间:2019-01-14 00:08:15

标签: gtk ada

我正在使用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/

2 个答案:

答案 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;