小部件更改会挂起GTK +中的主窗口

时间:2014-11-07 08:46:20

标签: gtk vala

我正在使用GTK +在Vala中编写程序。它有一个函数创建一个包含许多EventBox对象的ListBox。有一个问题:有一个功能可以下载图像并且需要花费很多时间,因此除非所有下载完成,否则主窗口不会显示。这不是我想要的,我希望主窗口出现,然后图像下载和显示。所以我将图像加载分离到单独的功能,但主窗口仍然不显示,除非所有下载完成。我做错了什么?

以下是我使用的功能:

foreach (MediaInfo post in feedPosts)  
     feedList.prepend(post);

foreach (PostBox box in feedList.boxes)
     box.loadImage();

(" feedList"是一个继承自Gtk.ListBox的类," box"是一个包含所有PostBox(继承自Gtk.EventBox)对象的列表)

这是feedList.prepend函数:

public void append(MediaInfo post)
{
    Gtk.Separator separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
    base.prepend(separator);
    PostBox box = new PostBox(post);
    base.prepend(box);
    boxes.append(box);      
}

这是PostBox类的构造函数和loadImage函数:

public PostBox(MediaInfo post)
{
    box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
    this.add(box);

    this.post = post;

    userToolbar = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);

    userNameLabel = new Gtk.Label("@" + post.postedUser.username);
    this.userNameLabel.set_markup(
            "<span underline='none' font_weight='bold' size='large'>" +
            post.postedUser.username + "</span>"
            );


    userToolbar.add(userNameLabel);
    box.pack_start(userToolbar, false, true);   

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

    box.add(new Gtk.Label(post.title));
    box.add(new Gtk.Label( post.likesCount.to_string() + " likes."));
    print("finished.\n");

    return;
}   

public void loadImage()
{
    var imageFileName = PhotoStream.App.CACHE_URL + getFileName(post.image.url);
    downloadFile(post.image.url, imageFileName);

    Pixbuf imagePixbuf = new Pixbuf.from_file(imageFileName);   
    imagePixbuf = imagePixbuf.scale_simple(IMAGE_SIZE, IMAGE_SIZE, Gdk.InterpType.BILINEAR);


    image.set_from_pixbuf(imagePixbuf);             
}

2 个答案:

答案 0 :(得分:0)

您已使用其他方法编写了下载操作,但操作仍然是同步,即阻止线程。你永远不想在GUI线程中进行计算或其他昂贵的事情,因为这会使GUI无响应。

您应该开始下载异步,并在下载完成后触发回调方法。在回调中,您可以将图像占位符更改为实际图像。

答案 1 :(得分:0)

我用多线程替换了所有 async 方法,现在它的工作方式与我希望它一样。