我正在使用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);
}
答案 0 :(得分:0)
您已使用其他方法编写了下载操作,但操作仍然是同步,即阻止线程。你永远不想在GUI线程中进行计算或其他昂贵的事情,因为这会使GUI无响应。
您应该开始下载异步,并在下载完成后触发回调方法。在回调中,您可以将图像占位符更改为实际图像。
答案 1 :(得分:0)
我用多线程替换了所有 async 方法,现在它的工作方式与我希望它一样。