2012-05-31 2 views
0

나는이 클래스를 만들었고 동일한 스레드에서 GUI로드가 매우 느리기 때문에 효율적 이유 때문에 다른 스레드로 축소판을 iconview에로드하려고합니다. 그러나 스레드를 만들면 작동하지 않으며 일부 축소판을 그리고 나서 사라집니다. 조인을 사용하면 작동합니다. 이건 내 코드입니다 :gtk에서 다른 스레드로 위젯을로드하는 방법은 무엇입니까? (vala)

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; 
} 

} 당신은 실제로 프로그램에서 스레드를 처리 할 필요가 없습니다

+0

당신이 최소한의, 독립적 인 테스트 케이스를 게시하면 도움이 훨씬 쉬울 것 (즉, 어떤 사람들이 컴파일하고 실행할 수) : 여기

은 예입니다. – nemequ

+0

@nemequ 감사합니다, 나는 그것을 시도했지만, 길을 찾을 수 없습니다 ... 나는 일반적으로 비동기적인 물건을 가진 매우 멍청하다 ... 여기 내 고통스러운 시도가있는 코드입니다. http : // pastebin.com/06Wz6Yfq – angrymadcat

+0

@nemequ 와우 !! 대단히 감사합니다. 매우 유용 할 것입니다. – angrymadcat

답변

3

- 당신은 단지 콘텐츠를로드하는 asynchronous method를 사용할 수 있습니다. 구체적으로는 Gdk.Pixbuf.new_from_stream_at_scale_async입니다.

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; 
} 
관련 문제