在GTK3树视图中包装文本

时间:2016-04-23 15:17:01

标签: c++ gtk3 gtkmm3

我无法在GTK3中获取TreeView以正确包装文本。

我将它设置为以这种方式包装:

    Gtk::TreeViewColumn* pColumn = mTreeView.get_column(2);
    static_cast<Gtk::CellRendererText *>(pColumn->get_first_cell())
        ->property_wrap_mode().set_value(Pango::WRAP_WORD_CHAR);
    static_cast<Gtk::CellRendererText *>(pColumn->get_first_cell())
        ->property_wrap_width().set_value(200);

这样做,文字被包裹,但是当我调整窗口大小并使其变大时,在文本上方和下方有很多丑陋的白色空间。看来,GTK根据包裹宽度保留了单元格的高度。这对我来说毫无意义。

我尝试在signal_check_resize中设置所需的设置并计算所需的宽度,如下所示:

        Gtk::TreeViewColumn* pColumn = mTreeView.get_column(2);
        auto width = this->get_allocated_width()
            - mTreeView.get_column(0)->get_width()
            - mTreeView.get_column(1)->get_width();
        static_cast<Gtk::CellRendererText *>(pColumn->get_first_cell())
            ->property_wrap_width().set_value(width-100);
        this->forceRecreateModel = true; //Needed to work

但这让我只能让窗户更大。在调整大小后,它不能缩小。

问题是,这是如何做得好的?

我在Arch linux上使用gtk3.20.3-1和gtkmm3.20.1-1。

编辑:修正了标题中的拼写错误...

1 个答案:

答案 0 :(得分:4)

最后我发现了如何做到这一点。

在窗口的设置中(对于窗口派生类的构造函数),必须将列设置为AUTOSIZE以允许缩小宽度。

//Last Column setup
{
    mTreeView.append_column("Translation", mColumns.mEnglish);
    Gtk::TreeViewColumn* pColumn = mTreeView.get_column(2);
    pColumn->set_sizing(Gtk::TreeViewColumnSizing::TREE_VIEW_COLUMN_AUTOSIZE);
    static_cast<Gtk::CellRendererText *>(pColumn->get_first_cell())
        ->property_wrap_mode().set_value(Pango::WRAP_WORD_CHAR);
}

还需要在每次调整大小时设置正确的包裹宽度。如果没有这个,行的高度就像当前设置的wrap_width一样大,而不考虑当前宽度(导致顶部有大的填充,当拉伸更多并且禁止使窗口变小时)。

此代码也在构造函数中。

this->signal_check_resize().connect([this]()
{
    //calculate remaining size
    Gtk::TreeViewColumn* pColumn = mTreeView.get_column(2);
    auto width = this->get_allocated_width()
        - mTreeView.get_column(0)->get_width()
        - mTreeView.get_column(1)->get_width()-30;

    //minimum reasonable size for column
    if(width < 150)
        width = 150;

    static_cast<Gtk::CellRendererText *>(pColumn->get_first_cell())
        ->property_wrap_width().set_value(width);

    //debounce
    static auto oldsize = 0;
    {
        oldsize = width;

        //trigger redraw of mTreeView (by clearing and refilling Model,
        //it is done in 100ms pulse)
        this->mRedrawNeeded = true;
    }
});

也许值得注意的是,我将mTreeView封装在Gtk :: ScrolledWindow中。所以这是一个在列设置之前出现的块。 :)

//in class is: Gtk::ScrolledWindow mScrollForResults;

//scrolling area
mGrid.attach(mScrollForResults, 0,2,10,1);
mScrollForResults.set_hexpand();
mScrollForResults.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
                             Gtk::PolicyType::POLICY_ALWAYS);
mScrollForResults.set_margin_top(10);
mScrollForResults.set_min_content_width(400);
mScrollForResults.set_min_content_height(200);
mScrollForResults.add(mTreeView);

//results treeView
mRefListStore = Gtk::ListStore::create(mColumns);
mTreeView.set_model(mRefListStore);
mTreeView.set_hexpand();
mTreeView.set_vexpand();