一次添加大量文本视图时出现gtkd性能问题

一次添加大量文本视图时出现gtkd性能问题,gtk,d,gtkd,Gtk,D,Gtkd,这里有一个简单的例子来说明这个问题。单击按钮时,应添加500个TextView对象,每个对象包含一些文本。实际发生的情况是,有一个很短的延迟,添加了500个空文本视图,有一个更长的延迟,然后它们都立即被文本填充,并且布局本身大小正确。代码如下: import gtk.Button; import gtk.Main; import gtk.MainWindow; import gtk.Notebook; import gtk.ScrolledWindow; import gtk.Statusbar

这里有一个简单的例子来说明这个问题。单击按钮时,应添加500个TextView对象,每个对象包含一些文本。实际发生的情况是,有一个很短的延迟,添加了500个空文本视图,有一个更长的延迟,然后它们都立即被文本填充,并且布局本身大小正确。代码如下:

import gtk.Button;
import gtk.Main;
import gtk.MainWindow;
import gtk.Notebook;
import gtk.ScrolledWindow;
import gtk.Statusbar;
import gtk.TextView;
import gtk.TextBuffer;
import gtk.UIManager;
import gtk.VBox;
import gtk.Window;

import std.stdio;

class UI : MainWindow
{
  Notebook notebook;

  this() {
    super("Test");
    setDefaultSize(200, 100);
    VBox box = new VBox(false, 2);
    notebook = new Notebook();
    Button button = new Button("add lines");
    button.addOnClicked(&addLines);
    box.packStart(notebook, true, true, 0);
    box.packStart(button, false, false, 2);
    add(box);
    showAll();
  }

  void addLines(Button b) {
    VBox box = new VBox(false, 2);
    for (int i = 0; i < 500; i++) {
      auto tv = new TextView();
      tv.getBuffer().setText("line");
      box.packStart(tv, false, false, 1);
    }
    ScrolledWindow swin = new ScrolledWindow(box);
    notebook.add(swin);
    showAll();
  }
}

void main(string[] args)
{
  Main.init(args);
  auto ui = new UI();
  Main.run();
}
导入gtk.按钮;
进口gtk.Main;
导入gtk.main窗口;
进口gtk笔记本;
导入gtk.scrolled窗口;
导入gtk.Statusbar;
导入gtk.TextView;
导入gtk.TextBuffer;
导入gtk.UIManager;
导入gtk.VBox;
导入gtk.Window;
进口std.stdio;
类用户界面:主窗口
{
笔记本;
这(){
超级(“测试”);
setDefaultSize(200100);
VBox box=新的VBox(false,2);
笔记本=新笔记本();
按钮按钮=新按钮(“添加行”);
按钮。addOnClicked(&addLines);
box.packStart(notebook,true,true,0);
包装启动(按钮,假,假,2);
添加(框);
showAll();
}
无效添加行(按钮b){
VBox box=新的VBox(false,2);
对于(int i=0;i<500;i++){
自动电视=新文本视图();
tv.getBuffer().setText(“行”);
packStart(电视,假,假,1);
}
ScrolledWindow swin=新的ScrolledWindow(框);
笔记本。添加(swin);
showAll();
}
}
void main(字符串[]args)
{
Main.init(args);
自动用户界面=新用户界面();
Main.run();
}


Edit:建议创建一组文本视图本质上是昂贵的,我应该使用treeview进行重写。

GTK是事件驱动的,并且使用消息泵。如果在回调中执行了长时间的操作,则永远不会让消息泵处理挂起的消息。您可以将回调中的代码替换为2秒钟的睡眠,效果是一样的:UI将在该时间段冻结

如果无法拆分操作,请使用文档中描述的d等效项:

/* computation going on */
...
  while (gtk_events_pending ())
      gtk_main_iteration ();
...
/* computation continued */

在每次循环迭代之间调用,它将给GTK一些时间来处理通过添加小部件生成的事件。

经过更多的谷歌搜索和实验,结果证明,GTKTextView本质上很难实例化,我不应该尝试创建这么多。根据中的建议,我将重新编写代码,改为使用GtkTreeView。

为什么会显示空文本视图?textview.getbuffer.settext()调用出现在vbox.packstart(textview)之前,因此即使在添加textview时出现延迟,我也希望它们看起来已完全填充。另外,为什么添加500个文本视图这么慢?这似乎不是一个太大的数字,我不记得在gtk2/haskell中有过同样的问题。我尝试使用gtk_events_pending,它确实保持了ui的响应性,但加载速度更慢。doh-我刚刚意识到我以前的haskell代码中使用的是GtkEntry,而不是GtkTextView。所以500个文本浏览量看起来太多了。同意,我会使用树状视图。