在 GTK3 树视图中包装文本
Wrapping text in GTK3 treeview
我无法让 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);
这行得通,文本被换行,但是当我调整 window 的大小并使其变大时,带有长文本的单元格上方和下方有很多丑陋的 white-space。看起来,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
但这只能让我window变大。调整大小后无法缩小
问题是,这是如何正确完成的?
我在 Arch linux.
上使用 gtk3.20.3-1 和 gtkmm3.20.1-1
编辑:修复了标题中的拼写错误...
最后我找到了方法。
在 window 的设置中(对我来说 window 派生 class 的构造函数)必须将列设置为 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 所必需的一样大,而不考虑当前宽度(导致顶部填充较大,当拉伸更多并禁止 window更小)。
此代码也在构造函数中。
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();
我无法让 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);
这行得通,文本被换行,但是当我调整 window 的大小并使其变大时,带有长文本的单元格上方和下方有很多丑陋的 white-space。看起来,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
但这只能让我window变大。调整大小后无法缩小
问题是,这是如何正确完成的?
我在 Arch linux.
上使用 gtk3.20.3-1 和 gtkmm3.20.1-1编辑:修复了标题中的拼写错误...
最后我找到了方法。
在 window 的设置中(对我来说 window 派生 class 的构造函数)必须将列设置为 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 所必需的一样大,而不考虑当前宽度(导致顶部填充较大,当拉伸更多并禁止 window更小)。
此代码也在构造函数中。
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();