Python 如何修复内容更改后GTK滚动窗口不更新滚动条的问题?

Python 如何修复内容更改后GTK滚动窗口不更新滚动条的问题?,python,gtk,pygtk,Python,Gtk,Pygtk,我希望在我的GTK应用程序中有一个图像,可以不断调整大小以适应其父容器 我通过在size allocate事件回调中获取父容器的大小,并根据这些大小调整图像的大小来实现这一点。当我把窗口变小时,这很好,但是当我想把它变大时,它拒绝调整大小,因为它必须至少和内容(图像)一样大 为了克服这个问题,我将图像放在了一个滚动窗口中,这样我就可以自由地调整窗口的大小 问题在于,当我将显示的图像切换到不同尺寸的图像时,ScrolledWindow似乎没有意识到这一点,而留给我的是一个内容大小错误的Scroll

我希望在我的GTK应用程序中有一个图像,可以不断调整大小以适应其父容器

我通过在size allocate事件回调中获取父容器的大小,并根据这些大小调整图像的大小来实现这一点。当我把窗口变小时,这很好,但是当我想把它变大时,它拒绝调整大小,因为它必须至少和内容(图像)一样大

为了克服这个问题,我将图像放在了一个滚动窗口中,这样我就可以自由地调整窗口的大小

问题在于,当我将显示的图像切换到不同尺寸的图像时,ScrolledWindow似乎没有意识到这一点,而留给我的是一个内容大小错误的ScrolledWindow和不必要的滚动条。但是,唉,我可以将鼠标悬停在滚动条上,它意识到它的内容太大,于是删除了滚动条。请参见下面的演示

我是否可以让这种“更正”行为立即发生,而不是当我将鼠标悬停在滚动条上时

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import GdkPixbuf


class Minimal(Gtk.Window):


    imageShown = 0
    img = Gtk.Image.new()
    pixbufRed = GdkPixbuf.Pixbuf.new_from_file("kirby_red.png")
    pixbufBlue = GdkPixbuf.Pixbuf.new_from_file("kirby_blue.png")
    pixbuf = None


    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_default_size(400,300)

        button = Gtk.Button.new_with_label("Swap Image")
        button.connect("clicked", self.on_button_click)

        self.pixbuf = self.pixbufRed
        self.img.set_from_pixbuf(self.pixbuf)

        scrolled = Gtk.ScrolledWindow()
        scrolled.connect("size-allocate", self.on_size_allocated);
        scrolled.add(self.img)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,spacing=0)
        box.pack_start(button, False, False, 0)
        box.pack_end(scrolled, True, True, 0)

        self.add(box)


    #swap image shown using imageShown flag to keep track
    def on_button_click(self, button):
        if(self.imageShown == 0):
            self.pixbuf = self.pixbufBlue
            self.imageShown = 1
        else:
            self.pixbuf = self.pixbufRed
            self.imageShown = 0
        self.img.set_from_pixbuf(self.pixbuf)


    def on_size_allocated(self, widget, allocation):
        scaledPixbuf = Minimal.scale_image_from_allocation_keep_aspect(self.pixbuf, allocation)
        self.img.set_from_pixbuf(scaledPixbuf)


    @staticmethod
    def scale_image_from_allocation_keep_aspect(pixbuf, allocation):
        imgWidth = pixbuf.get_width()
        imgHeight = pixbuf.get_height()

        parentWidth = allocation.width
        parentHeight = allocation.height

        aspectWidth = parentWidth/imgWidth
        aspectHeight= parentHeight/imgHeight

        aspect=0

        if(aspectWidth < aspectHeight):
            aspect = aspectWidth
        else:
            aspect = aspectHeight

        newWidth = imgWidth*aspect
        newHeight = imgHeight*aspect

        return pixbuf.scale_simple(newWidth, newHeight, GdkPixbuf.InterpType.BILINEAR)


win = Minimal()
win.show_all()
Gtk.main()
导入gi
gi.要求_版本(“Gtk”、“3.0”)
从gi.repository导入Gtk
从gi.repository导入GdkPixbuf
最小类(Gtk.Window):
图像显示=0
img=Gtk.Image.new()
pixbufRed=GdkPixbuf.Pixbuf.new_from_文件(“kirby_red.png”)
pixbufBlue=GdkPixbuf.Pixbuf.new_from_文件(“kirby_blue.png”)
pixbuf=无
定义初始化(自):
Gtk.Window.\uuuu初始化\uuuuu(自)
设置默认大小(400300)
按钮=Gtk.button.new_,带有_标签(“交换图像”)
按钮。连接(“点击”,自我。点击按钮)
self.pixbuf=self.pixbuffred
self.img.set_from_pixbuf(self.pixbuf)
scrolled=Gtk.scrolled窗口()
滚动。连接(“大小分配”,自我分配);
滚动添加(self.img)
长方体=Gtk.长方体(方向=Gtk.方向.垂直,间距=0)
包装启动(按钮,错误,错误,0)
box.pack_end(滚动,真,真,0)
self.add(框)
#使用ImageShowed标志交换显示的图像以保持跟踪
def on_按钮_单击(自身,按钮):
如果(self.imageShowed==0):
self.pixbuf=self.pixbufBlue
self.imageShowed=1
其他:
self.pixbuf=self.pixbuffred
self.imageShowed=0
self.img.set_from_pixbuf(self.pixbuf)
def on_size_allocated(自我、小部件、分配):
scaledPixbuf=最小值。从分配角度缩放图像(self.pixbuf,分配)
self.img.set_from_pixbuf(scaledPixbuf)
@静力学方法
def scale_image_从_分配_保留_方面(pixbuf,分配):
imgWidth=pixbuf.get_width()
imgHeight=pixbuf.get_height()
parentWidth=allocation.width
parentHeight=allocation.height
aspectWidth=parentWidth/imgWidth
aspectHeight=parentHeight/imgHeight
纵横比=0
如果(aspectWidth

大小分配
并不是更改小部件内容(如更改图像小部件的pixbuf)的正确位置,如果您尝试这样使用它,它通常无法正常工作。一旦确定了大小,定制容器小部件就可以更多地布局其子组件

在GTK 3中,我通常通过创建一个非常简单的自定义小部件来解决让图像填满可用空间的问题,如下所示:

导入gi
gi.要求_版本(“Gtk”、“3.0”)
从gi.repository导入Gtk、GdkPixbuf、Gdk
等级比例图像(Gtk.图纸区域):
def uuu init uuuu(self,pixbuf):
Gtk.图纸区域(自)
self.pixbuf=pixbuf
def do_图纸(自身、cr):
alloc,baseline=self.get\u allocated\u size()
系数=min(alloc.width/self.pixbuf.get_width(),alloc.height/self.pixbuf.get_height())
cr.刻度(因数,因数)
Gdk.cairo\u set\u source\u pixbuf(cr,self.pixbuf,0,0)
cr.油漆()
win=Gtk.Window()
img=ScaleImage(GdkPixbuf.Pixbuf.new_from_文件(“file.png”))
win.add(img)
赢,全力以赴
Gtk.main()


我还没有尝试过,但在GTK 4中,您应该可以使用它来获得相同的效果,而无需自定义小部件。

要做到这一点,只需在ScaleImage类中添加一个change_image函数,该函数更改了pixbuf并称为self.queue_draw。谢谢