使用(Py)GTK调整大小时自动缩放图像 [英] Automatic image scaling on resize with (Py)GTK
问题描述
我在一个可调整大小的窗口中有一个 GtkImage
小部件,并且存储了我想要填充的图像的引用 GdkPixBuf
GtkImage
with。
我可以将 GdkPixBuf
使用此方法填充 GtkImage
小部件:
def update_image(self, widget = None,data = None):
#获取源像素图的大小
src_width,src_height = self.current_image.get_width(),self.current_image.get_height()
#获取小部件区域的大小$ b $ widget = self.builder.get_object('image')
allocation = widget.get_allocation()
dst_width,dst_height = allocation.width,allocation .height
#比例保持比例
scale = min(float(dst_width)/ src_width,float(dst_height)/ src_height)
new_width = int(scale * src_width)
new_height = int(scale * src_height)
pixbuf = self.current_image.scale_simple(new_width,new_height,gt k.gdk.INTERP_BILINEAR)
#将生成的pixbuf放入GtkImage部件中
widget.set_from_pixbuf(pixbuf)
当我手动调用 update_image
时,它按预期工作。现在我想在GtkImage窗口小部件的大小调整时自动进行缩放。我最好的解决方案是将 update_image
方法绑定到窗口的 configure-event
GTK事件。每次更改窗口大小后,图像的确可以正确缩放。然而,我有这个解决方案的两个问题:
- 我只能让窗口变大。一旦图像被放大,GTK不会让我调整窗口的大小,因为窗口不能小于它的小部件。我明白为什么它会这样工作,但我不知道如何改变这种行为。
- 也许这没什么大不了,但我更喜欢GtkImage部件中的事件,而不是
对于这样一个小问题的长期解释,我很抱歉,希望您能帮助您我相信你可以使用 / widget-gtkwidget.html#signal-gtkwidget--expose-event\">expose-event 信号用于图像缩放。将图像添加到可滚动容器中应该可以解决窗口大小调整的问题。请检查下面的示例是否适合您。
导入gtk
$ b $ class ScaleImage:
def __init __(self):
self.temp_height = 0
self.temp_width = 0
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
image = gtk.Image()
image.set_from_file('/ home / my_test_image.jpg')
self.pixbuf = image.get_pixbuf()
image.connect('expose-event',self.on_image_resize,window)
box = gtk.ScrolledWindow()
box.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
box.add(image)
window.add (box)
window.set_size_request(300,300)
window.show_all()
$ b $ def on_image_resize(self,widget,event,window):
allocation = widget.get_allocation()
如果self.temp_height!= allocation.height或self.temp_width!= allocation.width:
self.temp_height = allocation.height
self.temp_width = allocation.width
pixbuf = self.pixbuf.scale_simple(allocation.width,allocation.height,gtk.gdk.INTERP_BILINEAR)
widget.set_from_pixbuf(pixbuf)
def close_application(self,widget,event,data = None):
gtk.main_quit()
return False
if __name__ ==__main__:
ScaleImage()
gtk.main()
希望这有助于您,
I have a GtkImage
widget in a resizable window and a reference GdkPixBuf
storing the image I want to fill the GtkImage
with.
I can scale the GdkPixBuf
to fill the GtkImage
widget using this method:
def update_image(self, widget=None, data=None):
# Get the size of the source pixmap
src_width, src_height = self.current_image.get_width(), self.current_image.get_height()
# Get the size of the widget area
widget = self.builder.get_object('image')
allocation = widget.get_allocation()
dst_width, dst_height = allocation.width, allocation.height
# Scale preserving ratio
scale = min(float(dst_width)/src_width, float(dst_height)/src_height)
new_width = int(scale*src_width)
new_height = int(scale*src_height)
pixbuf = self.current_image.scale_simple(new_width, new_height, gtk.gdk.INTERP_BILINEAR)
# Put the generated pixbuf in the GtkImage widget
widget.set_from_pixbuf(pixbuf)
When I call update_image
manually it works as expected. Now I want the scaling to occur automatically when the GtkImage widget is resized. The best solution I came with was to bind the update_image
method to the configure-event
GTK event of the window. After each size change of the window, the image is indeed properly scaled. However I have two issues with this solution:
- I can only make the window bigger. Once the image has been upscaled, GTK won't let me resize the window smaller because the window can't be smaller than its widgets. I understand why it works like that but I don't know how to change this behaviour.
- Maybe this is no big deal but I would have preferred an event from the GtkImage widget instead of the top-level window.
I am sorry for the long explanation of such a trivial problem, I hope you'll be able to help me.
I believe you could use expose-event signal of the widget for image scaling. Also adding image into scrollable container should fix the problem with window resize. Please check if an example below would work for you.
import gtk
class ScaleImage:
def __init__(self):
self.temp_height = 0
self.temp_width = 0
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
image = gtk.Image()
image.set_from_file('/home/my_test_image.jpg')
self.pixbuf = image.get_pixbuf()
image.connect('expose-event', self.on_image_resize, window)
box = gtk.ScrolledWindow()
box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
box.add(image)
window.add(box)
window.set_size_request(300, 300)
window.show_all()
def on_image_resize(self, widget, event, window):
allocation = widget.get_allocation()
if self.temp_height != allocation.height or self.temp_width != allocation.width:
self.temp_height = allocation.height
self.temp_width = allocation.width
pixbuf = self.pixbuf.scale_simple(allocation.width, allocation.height, gtk.gdk.INTERP_BILINEAR)
widget.set_from_pixbuf(pixbuf)
def close_application(self, widget, event, data=None):
gtk.main_quit()
return False
if __name__ == "__main__":
ScaleImage()
gtk.main()
hope this helps, regards
这篇关于使用(Py)GTK调整大小时自动缩放图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!