如何将背景图像添加到GTK TreeView?
我想有一个GTK树视图与背景图像,如下图所示 我已经找到了设置小部件背景颜色的方法,但似乎没有一种方法可以设置背景pixbuf或其他图像格式 我将Python与PyGTK结合使用,但任何带有GTK绑定的语言的答案都是可以接受的 带背景图像的gtkTreeView模型: 第一次尝试 根据Jong Bor的建议,我尝试了以下方法:如何将背景图像添加到GTK TreeView?,gtk,pygtk,gtktreeview,Gtk,Pygtk,Gtktreeview,我想有一个GTK树视图与背景图像,如下图所示 我已经找到了设置小部件背景颜色的方法,但似乎没有一种方法可以设置背景pixbuf或其他图像格式 我将Python与PyGTK结合使用,但任何带有GTK绑定的语言的答案都是可以接受的 带背景图像的gtkTreeView模型: 第一次尝试 根据Jong Bor的建议,我尝试了以下方法: style = treeview.get_style().copy() img_pixbuf = gtk.gdk.pixbuf_new_from_file(image_f
style = treeview.get_style().copy()
img_pixbuf = gtk.gdk.pixbuf_new_from_file(image_filename)
img_pixmap = img_pixbuf.render_pixmap_and_mask()[0]
for state in (gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT,
gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE):
style.bg_pixmap[state] = img_pixmap
treeview.set_style(style)
起初,这似乎没有任何效果,但在我的树状视图中选择一个项目后,我观察到以下情况:
style = treeview.get_style().copy()
img_pixbuf = gtk.gdk.pixbuf_new_from_file(image_filename)
img_pixmap = img_pixbuf.render_pixmap_and_mask()[0]
for state in (gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT,
gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE):
style.bg_pixmap[state] = img_pixmap
treeview.set_style(style)
选择行时,部分背景“显示通过”
请注意,我使用的是基于模型的背景图像,只是出于测试目的,它有一些蓝色
然后,我激活了GUI的一部分,该部分清除树视图的内容并重新绘制,并观察到:
但是,只要我向TreeView添加一些内容,背景就会消失,因此我仍然不确定这是否朝着正确的方向发展。我怀疑,由于每个单元格都有一个控制其外观的渲染器,因此您必须以某种方式逐单元格修改TreeView单元格 无论如何,以下代码可能值得一试未经测试、不完整的代码:
# Get the treeview's style
style = treeview.get_style().copy()
# Change the bg_pixmap attribute
# It's an array with one pixbuf for every widget state, so
# you probably want to replace each of the default
# pixmap's with your own image(s)
#
style.bg_pixmap[0] = your_pixmap
style.bg_pixmap[1] = your_pixmap
style.bg_pixmap[2] = your_pixmap
style.bg_pixmap[3] = your_pixmap
style.bg_pixmap[4] = your_pixmap
# Set the modified style
treeview.set_style(style)
bg_pixmap属性记录在中
我不确定数组位置如何映射到小部件状态。如果与C++相同,则为:
0 - STATE_NORMAL
1 - STATE_ACTIVE
2 - STATE_PRELIGHT
3 - STATE_SELECTED
4 - STATE_INSENSITIVE
我怀疑,由于每个单元都有一个控制其外观的渲染器,因此您必须以某种方式逐个单元修改treeview单元 无论如何,以下代码可能值得一试未经测试、不完整的代码:
# Get the treeview's style
style = treeview.get_style().copy()
# Change the bg_pixmap attribute
# It's an array with one pixbuf for every widget state, so
# you probably want to replace each of the default
# pixmap's with your own image(s)
#
style.bg_pixmap[0] = your_pixmap
style.bg_pixmap[1] = your_pixmap
style.bg_pixmap[2] = your_pixmap
style.bg_pixmap[3] = your_pixmap
style.bg_pixmap[4] = your_pixmap
# Set the modified style
treeview.set_style(style)
bg_pixmap属性记录在中
我不确定数组位置如何映射到小部件状态。如果与C++相同,则为:
0 - STATE_NORMAL
1 - STATE_ACTIVE
2 - STATE_PRELIGHT
3 - STATE_SELECTED
4 - STATE_INSENSITIVE
使用GTK3和gtkmm可以使用CSS,但图像需要作为文件或资源提供 这里我假设treeview是子类:
class MyTreeView : public Gtk::TreeView { .. };
为您的treeview设置名称,然后向其添加CSS样式:
MyTreeView::MyTreeView () {
set_name ("MyTreeView");
auto css = Gtk::CssProvider::create ();
auto sc = get_style_context ();
string path_to_img = "my-image.png";
string css_data =
ustring::compose (
"#MyTreeView { background-image: url(\"%1\");"
" background-repeat: no-repeat;"
" background-position: 50%% 50%%;"
" }\n"
"#MyTreeView .hide_bg { background-image: none; }",
path_to_img);
try {
css->load_from_data (css_data);
} catch (Gtk::CssProviderError &e) {
cout "error: attempted to set background image: " << path_to_img.c_str () << ": " << e.what () << endl;
}
auto screen = Gdk::Screen::get_default ();
sc->add_provider_for_screen (screen, css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
到CSS
然后,可以使用以下方法隐藏或显示背景图像:
if (!hide) {
auto sc = get_style_context ();
if (!sc->has_class ("hide_bg")) sc->add_class ("hide_bg");
} else {
auto sc = get_style_context ();
if (sc->has_class ("hide_bg")) sc->remove_class ("hide_bg");
}
使用GTK3和gtkmm可以使用CSS,但图像需要作为文件或资源提供 这里我假设treeview是子类:
class MyTreeView : public Gtk::TreeView { .. };
为您的treeview设置名称,然后向其添加CSS样式:
MyTreeView::MyTreeView () {
set_name ("MyTreeView");
auto css = Gtk::CssProvider::create ();
auto sc = get_style_context ();
string path_to_img = "my-image.png";
string css_data =
ustring::compose (
"#MyTreeView { background-image: url(\"%1\");"
" background-repeat: no-repeat;"
" background-position: 50%% 50%%;"
" }\n"
"#MyTreeView .hide_bg { background-image: none; }",
path_to_img);
try {
css->load_from_data (css_data);
} catch (Gtk::CssProviderError &e) {
cout "error: attempted to set background image: " << path_to_img.c_str () << ": " << e.what () << endl;
}
auto screen = Gdk::Screen::get_default ();
sc->add_provider_for_screen (screen, css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
到CSS
然后,可以使用以下方法隐藏或显示背景图像:
if (!hide) {
auto sc = get_style_context ();
if (!sc->has_class ("hide_bg")) sc->add_class ("hide_bg");
} else {
auto sc = get_style_context ();
if (sc->has_class ("hide_bg")) sc->remove_class ("hide_bg");
}
谢谢你的建议。不幸的是,我尝试了这种方法,但没有任何明显的效果。我还尝试直接设置bg_pixmap值,而不是首先复制样式并将其设置回小部件上,但也不起作用。我认为bg_pixmap只影响窗口背景可见的小部件部分,但是TreeView小部件用白色填充覆盖窗口背景。这是意料之中的。在看到你的评论之前,我对答案进行了编辑,以表明这确实是一个遥远的目标。由于每个单元都有一个允许更改其外观的渲染器,所以蛮力方法是修改每个单元的背景。除非对Gtk的内部工作有更深入了解的人能够对这个问题有所了解……在进一步的调查中,我发现设置bg_pixmap属性确实有一些效果。我将bg_pixmap数组中的每个值设置为我的图像的pixmap,这会导致所选行的选择颜色成为我图像的一部分。有时图像甚至会以平铺方式显示为背景,但仅当树视图为空时。我会给我的问题添加一个截图。谢谢你的建议。不幸的是,我尝试了这种方法,但没有任何明显的效果。我还尝试直接设置bg_pixmap值,而不是首先复制样式并将其设置回小部件上,但也不起作用。我认为bg_pixmap只影响窗口背景可见的小部件部分,但是TreeView小部件用白色填充覆盖窗口背景。这是意料之中的。在看到你的评论之前,我对答案进行了编辑,以表明这确实是一个遥远的目标。由于每个单元都有一个允许更改其外观的渲染器,所以蛮力方法是修改每个单元的背景。除非对Gtk的内部工作有更深入了解的人能够对这个问题有所了解……在进一步的调查中,我发现设置bg_pixmap属性确实有一些效果。我将bg_pixmap数组中的每个值设置为我的图像的pixmap,这会导致所选行的选择颜色成为我图像的一部分。有时图像甚至会以平铺方式显示为背景,但仅当树视图为空时。我将在我的问题中添加一个屏幕截图。填充树视图后调用treeview.show_会使背景可见吗?还有一个不切实际的建议:既然选择了
行使背景可见,执行类似treeview.get_selection.select_all的操作以选择所有行。@Jong show_all似乎没有效果。此外,除非整个树视图已满,否则选择“全部”将无法显示背景,即使如此,该界面也无法为用户工作-/填充树视图后调用treeview.show_all是否会使背景可见?另外,还有一个粗俗的建议:因为选择一行会使背景可见,所以可以执行类似于treeview.get\u selection.select\u all的操作来选择所有行。@Jong show\u all似乎没有效果。此外,除非整个树视图已满,否则选择“全部”将无法显示背景,即使如此,该界面也无法为用户工作-/