问题
I created this class, And I want to load thumbnails into the iconview as a different thread for efficiency reasons, because the gui load very slow if I do it in the same thread. But when I create the thread, it doesn't works, it draw some thumbnails and then they dissapear. When I use join, it works. This is my code:
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;
}
}
回答1:
You don't actually need to deal with threads in your program--you can just use an asynchronous method to load the content. Specifically, Gdk.Pixbuf.new_from_stream_at_scale_async.
Here is an example:
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;
}
来源:https://stackoverflow.com/questions/10831889/how-to-load-a-widget-as-a-different-thread-in-gtk-vala