python - 如何设置 GtkImage 的大小

标签 python gtk3 pygobject

我正在从网页下载图像,该图像太大(通常最大边缘为 600 像素),我想将其缩小以适合 220x220 像素的框。

我的代码可以工作 - 除了最终大小。下载图像,然后放入 GtkImage(它来自 Glade 布局)。我将其下载到临时文件中,因为我似乎无法直接将数据从网站传输到图像中。现在的问题是该图像在应用程序中显示时太大。

f = tempfile.NamedTemporaryFile()
try:
    res = urllib2.urlopen('http://hikingtours.hk/images/meetingpoint_%s.jpg'% (self.tours[tourid]['id'], ))
    f.write(res.read())

    # This f.read() call is necassary, without it, the image
    # can not be set properly.
    f.read()
    self.edit_tour_meetingpoint_image.set_from_file(f.name)
    self.edit_tour_meetingpoint_image.show()

except:
    raise

f.close()

顺便说一句,我很想摆脱临时文件构造:)

请注意,我使用的是 GTK3。

最佳答案

将 Gdk.Pixbuf.new_from_file_at_scale() 与 Gtk.Image.set_from_pixbuf() 一起使用:

pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(f.name, width=220, height=220,
                                                 preserve_aspect_ratio=False)
self.edit_tour_meetingpoint_image.set_from_pixbuf(pixbuf)

如果您想保留宽高比,只需将该参数设置为 True 或使用:GdkPixbuf.Pixbuf.new_from_file_at_size(f.name, width=220, height=220)

旁注:在使用该文件之前需要调用 read() 的原因是它已被缓冲并且尚未写入磁盘。读取调用导致缓冲区刷新,更清晰的技术(从可读性的角度来看)是调用flush()而不是read()。

如果您想删除临时文件,请使用 Gio 模块和流式 pixbuf:

from gi.repository import Gtk, GdkPixbuf, Gio

file = Gio.File.new_for_uri('http://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png')
pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(file.read(cancellable=None),
                                                   width=220, height=220,
                                                   preserve_aspect_ratio=False,
                                                   cancellable=None)
self.edit_tour_meetingpoint_image.set_from_pixbuf(pixbuf)

您可以进一步使用异步图像流,然后在 pixbuf 准备就绪时将完成的结果注入(inject)到应用程序中,从而在文件传输期间保持 UI 中的交互性:

from gi.repository import Gtk, GdkPixbuf, Gio

# standin image until our remote image is loaded, this can also be set in Glade
image = Gtk.Image.new_from_icon_name('image-missing', Gtk.IconSize.DIALOG)

def on_image_loaded(source, async_res, user_data):
    pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(async_res)
    image.set_from_pixbuf(pixbuf)

file = Gio.File.new_for_uri('http://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png')
GdkPixbuf.Pixbuf.new_from_stream_at_scale_async(file.read(cancellable=None),
                                                220, 220, # width and height
                                                False,    # preserve_aspect_ratio
                                                None,     # cancellable
                                                on_image_loaded, # callback,
                                                None)     # user_data

请注意,由于 user_data 参数,我们无法在异步版本中使用 Nice 关键字参数。这在 pygobject 3.12 中消失了,其中 user_data 如果不使用(或也用作关键字参数)实际上可以被保留。

关于python - 如何设置 GtkImage 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24436585/

相关文章:

localization - 使用 Python/PyGObject 在 Windows 中加载 GTK-Glade 翻译

python - 如何创建具有可调参数的 numba 可调用对象?

python 日志管理器

python - 如何在图表中标记特定类型(例如 030T)的所有三元组?

python - 在没有 Gtk.main() 的情况下,窗口不会在 GTK3 的 python 解释器中显示

python - 如何在 python 和 GTK 3 中编写自定义 Gtk.CellRenderer?

python - 对 2 个数据帧中 2 列的所有组合求和

python - 如何使用 Gtk.events_pending?

c++ - GtkSpinButton 是否能够设置时间间隔?

python - Gtk.Treeview 通过信号和代码取消选择行