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

如何在GTKMM4中让Gtk::Viewport固定尺寸以实现滚动?

解决Gtk::Viewport无法滚动的问题

问题原因

你当前的布局中,Gtk::Box默认会强制子部件(Gtk::Viewport)填充可用空间,同时Gtk::Viewport会自适应内容(LargeWidget)的尺寸,导致它被拉伸至100x200,失去滚动触发条件。

可行解决方案

方案一:调整现有布局,限制Viewport尺寸

通过设置Viewport的尺寸请求,并禁止它在布局中自动扩展,同时修正滚动条的调整参数:

#include <gtkmm.h>

class LargeWidget : public Gtk::DrawingArea {
public:
    LargeWidget(int width, int height) {
        set_content_width(width);
        set_content_height(height);
    }
};

class Window : public Gtk::Window {
    Gtk::Box box;
    Gtk::Scrollbar scrollbar;
    Glib::RefPtr<Gtk::Adjustment> v;
    Gtk::Viewport viewport;
    LargeWidget large_widget;

public:
    Window() : v(Gtk::Adjustment::create(0, 0, 200, 1, 10, 10)),
               viewport(Gtk::Adjustment::create(0,0,100), v),
               large_widget(100, 200) {
        scrollbar.set_orientation(Gtk::Orientation::VERTICAL);
        scrollbar.set_adjustment(viewport.get_vadjustment());

        viewport.set_child(large_widget);
        // 限制Viewport的尺寸请求,禁止垂直方向自动扩展
        viewport.set_size_request(100, 100);
        viewport.set_vexpand(false);
        viewport.set_hexpand(true); // 水平方向填充窗口宽度(减去滚动条)

        box.set_orientation(Gtk::Orientation::HORIZONTAL);
        box.append(viewport);
        box.append(scrollbar);

        set_default_size(100, 100);
        set_child(box);
    }
};

int main(int argc, char **argv) {
    auto app = Gtk::Application::create("hu.aszn.playground");
    return app->make_window_and_run<Window>(argc, argv);
}

方案二:使用Gtk::ScrolledWindow(推荐)

Gtk::ScrolledWindow已经封装了Viewport和滚动条的逻辑,无需手动组合,代码更简洁:

#include <gtkmm.h>

class LargeWidget : public Gtk::DrawingArea {
public:
    LargeWidget(int width, int height) {
        set_content_width(width);
        set_content_height(height);
    }
};

class Window : public Gtk::Window {
    Gtk::ScrolledWindow scrolled_window;
    LargeWidget large_widget;

public:
    Window() : large_widget(100, 200) {
        // 设置滚动条策略:垂直滚动条按需显示,水平滚动条永不显示
        scrolled_window.set_policy(Gtk::PolicyType::NEVER, Gtk::PolicyType::AUTOMATIC);
        scrolled_window.set_child(large_widget);

        set_default_size(100, 100);
        set_child(scrolled_window);
    }
};

int main(int argc, char **argv) {
    auto app = Gtk::Application::create("hu.aszn.playground");
    return app->make_window_and_run<Window>(argc, argv);
}

关键说明

  • 方案一中,set_vexpand(false)阻止Viewport在垂直方向被Box拉伸,set_size_request固定其初始高度,当内容超出时,Adjustment会触发滚动。
  • 方案二中,Gtk::ScrolledWindow会自动根据内容和自身尺寸判断是否显示滚动条,无需手动管理Adjustment和滚动条的绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:55:01