You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何去除Gtk4中Gtk.Box/Gtk.Grid内Gtk.Image的周边内边距?

解决Gtk4中Gtk.Image周边内边距无法消除的问题

你遇到的上下内边距问题核心原因是**set_size_request的参数顺序搞反了**——Gtk.Image的set_size_request(width, height)方法第一个参数是宽度,第二个是高度,但你代码里传的是(img_height, img_width),导致Image的尺寸被颠倒,Gtk为了维持图片的原始比例,自动在上下填充了大量空白。

下面是具体的修复方案:

1. 修正尺寸请求的参数顺序

把创建Image时的尺寸请求代码调换参数顺序:

# 原错误代码
# image.set_size_request(img_height, img_width)
# 修正后
image.set_size_request(img_width, img_height)

2. 优化布局与CSS消除冗余空白

即使修正了尺寸,还可以通过调整布局属性和CSS来让整体更紧凑:

  • 给承载Image和Label的垂直Box设置valign=Gtk.Align.START,避免Box被Grid拉伸导致Label下方出现空白;
  • 通过CSS移除各部件的默认内外边距。

修正后的完整代码

import gi
import sys

gi.require_version('Gtk', '4.0')

from gi.repository import Gtk, GdkPixbuf


def create_image(file_name, img_width, cssProvider = None):

    info = 'file:' + file_name

    box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    # 设置Box垂直对齐为顶部,避免被拉伸
    box.set_valign(Gtk.Align.START)
    box.set_hexpand(True)

    if cssProvider:
        box.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
        box.add_css_class('thumbnail')

    # add image to top
    pixbuf = GdkPixbuf.Pixbuf.new_from_file(file_name)

    # calculate height to keep width and aspect ratio
    img_height = pixbuf.get_height() * img_width / pixbuf.get_width()

    image = Gtk.Image.new_from_pixbuf(pixbuf)
    # 修正set_size_request的参数顺序:宽在前,高在后
    image.set_size_request(img_width, img_height)

    if cssProvider:
        image.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
        image.add_css_class('thumbnail-image')

    box.append(image)

    # add label to bottom
    label = Gtk.Label(label=info)

    if cssProvider:
        label.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
        label.add_css_class('thumbnail-label')

    box.append(label)

    return box


class MainWindow(Gtk.ApplicationWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 启用CSS Provider
        self.cssProvider = Gtk.CssProvider()
        self.cssProvider.load_from_data(b"""
.thumbnail {background-color: white; color: black; border: 1px solid #ddd; margin: 5px; padding: 0; }
.thumbnail-label { font-size: 12pt; margin: 0; padding: 4px 0; }
.thumbnail-image { margin: 0; padding: 0; }
""")

        self.set_default_size(900, 600)
        self.set_title("MyApp")

        self.grid = Gtk.Grid()
        # 给Grid设置列间距,避免图片挤在一起
        self.grid.set_column_spacing(10)
        self.grid.set_row_spacing(10)

        self.window = Gtk.ScrolledWindow()
        self.window.set_child(self.grid)

        self.set_child(self.window)

        idx = 0
        prev = None

        for idx in range(0,20):
            # 4 columns
            i = int(idx / 4)
            j = int(idx % 4)

            image = create_image('frog.jpg', 1920/4 - 10, self.cssProvider)

            self.grid.attach(image, j, i, 1, 1)


class MyApp(Gtk.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)
    
    def on_activate(self, app):
        self.win = MainWindow(application=app)
        self.win.present()

app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)

说明

  • 修正尺寸参数后,Image会按照计算的宽高正确显示,不会出现比例不匹配导致的内边距;
  • 设置Box的valign=START可以防止Grid拉伸Box,避免Label下方出现多余空白;
  • CSS里给Label保留了少量上下内边距(padding:4px 0),让文字不会紧贴Image,你可以根据需要调整为0。

内容的提问来源于stack exchange,提问作者TomasV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:25:34