Multithreading 如何在gtk中将小部件作为不同的线程加载?(瓦拉)

Multithreading 如何在gtk中将小部件作为不同的线程加载?(瓦拉),multithreading,gtk,vala,Multithreading,Gtk,Vala,我创建了这个类,出于效率考虑,我想将缩略图作为不同的线程加载到iconview中,因为如果在同一个线程中加载,gui的加载速度会非常慢。但是当我创建线程时,它不起作用,它绘制了一些缩略图,然后它们消失了。当我使用join时,它可以工作。这是我的代码: public class FotoThumbnailPane : Gtk.ScrolledWindow{ private FotoThumbnailPane_i pane; private string namet; public

我创建了这个类,出于效率考虑,我想将缩略图作为不同的线程加载到iconview中,因为如果在同一个线程中加载,gui的加载速度会非常慢。但是当我创建线程时,它不起作用,它绘制了一些缩略图,然后它们消失了。当我使用join时,它可以工作。这是我的代码:

    public class FotoThumbnailPane : Gtk.ScrolledWindow{

private FotoThumbnailPane_i pane;   
private string namet;

public FotoThumbnailPane(string name){
    this.namet = name;
}

public void set_imagelist(fileutils.ImageList image_list){
    pane = new FotoThumbnailPane_i(image_list);
    this.add (pane);
    this.set_min_content_width(140);
    this.show_all();
}

    //This is my threaded function
    public void* load_thumbs(){

    pane.set_visible(false);
    pane.newmodel = new Gtk.ListStore (2, typeof (Gdk.Pixbuf), typeof (string));
    pane.set_selection_mode (Gtk.SelectionMode.SINGLE);
    pane.set_pixbuf_column (0);
    pane.set_model(pane.newmodel);

    string icon_style = """
            .thumbnail-view {
                background-color: #FFFFFF;
            }
            .thumbnail-view:selected {
                background-color: #9D9D9D;
                border-color: shade (mix (rgb (34, 255, 120), #fff, 0.5), 0.9);
            }
        """;

    var icon_view_style = new Gtk.CssProvider ();

        try {
            icon_view_style.load_from_data (icon_style, -1);
        } catch (Error e) {
            warning (e.message);
        }
        pane.get_style_context ().add_class ("thumbnail-view");
    pane.get_style_context ().add_provider (icon_view_style, Gtk.STYLE_PROVIDER_PRIORITY_THEME);

    //Add thumbnails to the iconview
    string buff;
    for(int i=1; i<pane.image_list.size; i++){
    buff = pane.image_list.get_full_filename(i);
    stdout.printf("Added %s to thumbnail\n", buff);
            var image = new Gdk.Pixbuf.from_file_at_scale(buff, 110, 80, false);
            // Add the wallpaper name and thumbnail to the IconView
            Gtk.TreeIter root;
            pane.newmodel.append(out root);
            pane.newmodel.set(root, 0, image, -1);
            pane.newmodel.set(root, 1, pane.image_list.get_filename(i), -1);

            // Select the thumbnail if it is the first in list
            if (i==0) {
                pane.select_path (pane.newmodel.get_path (root));
            }    
            pane.iters.append (root);
    }
    pane.set_sensitive(true);
    this.queue_draw();
return null;
}
公共类FotoThumbnailPane:Gtk.scrolled窗口{
私人FotoThumbnailPane_i pane;
私有字符串名称;
公共FOTOTUMBNAILPANE(字符串名称){
this.namet=name;
}
public void set_imagelist(fileutils.imagelist image_list){
窗格=新的FOTOTUMBNAILPANE_i(图像列表);
添加(窗格);
这个。设置内容宽度(140);
这个。全部显示();
}
//这是我的线程函数
public void*load_thumbs(){
窗格。设置_可见(假);
pane.newmodel=newgtk.ListStore(2,typeof(Gdk.Pixbuf),typeof(string));
pane.set_selection_mode(Gtk.SelectionMode.SINGLE);
pane.set_pixbuf_列(0);
pane.set_model(pane.newmodel);
字符串图标_style=“”
.缩略图视图{
背景色:#FFFFFF;
}
.缩略图视图:选中{
背景色:#9D9D9D;
边框颜色:阴影(混合(rgb(34,255,120),#fff,0.5),0.9);
}
""";
var icon_view_style=new Gtk.CssProvider();
试一试{
图标\视图\样式。从\数据加载\样式(图标\样式,-1);
}捕获(错误e){
警告(e.message);
}
pane.get_style_context().添加_类(“缩略图视图”);
pane.get_style_context().add_provider(图标_view_style,Gtk.style_provider_PRIORITY_主题);
//将缩略图添加到iconview
琴弦浅黄色;

对于(inti=1;i您实际上不需要处理程序中的线程——您可以使用加载内容

以下是一个例子:

public async void load (Gtk.Image img, string filename) {
  GLib.File file = GLib.File.new_for_commandline_arg (filename);
  try {
    GLib.InputStream stream = yield file.read_async ();
    Gdk.Pixbuf pixbuf = yield Gdk.Pixbuf.new_from_stream_at_scale_async (stream, 320, -1, true);
    img.set_from_pixbuf (pixbuf);
  } catch ( GLib.Error e ) {
    GLib.error (e.message);
  }
}

private static int main (string[] args) {
  GLib.return_val_if_fail (args.length > 1, -1);

  Gtk.init (ref args);

  Gtk.Window win = new Gtk.Window ();
  win.destroy.connect (() => {
      Gtk.main_quit ();
    });

  Gtk.Image image = new Gtk.Image ();
  win.add (image);

  load.begin (image, args[1], (obj, async_res) => {
      GLib.debug ("Finished loading.");
    });

  win.show_all ();

  Gtk.main ();

  return 0;
}

实际上,您不需要处理程序中的线程,只需使用加载内容即可

以下是一个例子:

public async void load (Gtk.Image img, string filename) {
  GLib.File file = GLib.File.new_for_commandline_arg (filename);
  try {
    GLib.InputStream stream = yield file.read_async ();
    Gdk.Pixbuf pixbuf = yield Gdk.Pixbuf.new_from_stream_at_scale_async (stream, 320, -1, true);
    img.set_from_pixbuf (pixbuf);
  } catch ( GLib.Error e ) {
    GLib.error (e.message);
  }
}

private static int main (string[] args) {
  GLib.return_val_if_fail (args.length > 1, -1);

  Gtk.init (ref args);

  Gtk.Window win = new Gtk.Window ();
  win.destroy.connect (() => {
      Gtk.main_quit ();
    });

  Gtk.Image image = new Gtk.Image ();
  win.add (image);

  load.begin (image, args[1], (obj, async_res) => {
      GLib.debug ("Finished loading.");
    });

  win.show_all ();

  Gtk.main ();

  return 0;
}

如果您发布了一个最小的、自包含的测试用例(即,人们可以编译和执行的东西),那么提供帮助就会容易得多.@nemeq谢谢,我已经试过了,但是找不到方法…我对异步的东西很在行…下面是我痛苦尝试的代码@nemeq哇!!非常感谢,我认为它会非常有用!!代码工作:)如果你发布一个最小的、自包含的测试用例,帮助会容易得多(也就是说,人们可以编译和执行的东西)。@nemeq谢谢,我已经尝试过了,但找不到方法……我对异步的东西非常熟悉……下面是我痛苦尝试的代码@nemeq哇!!非常感谢,我认为这将非常有用!!代码工作:)