2011-03-21 99 views
2

我想要有一个背景图像的GTK TreeView,如下面的模型所示。如何添加背景图片到GTK TreeView?

我已经找到了设置窗口背景颜色的方法,但似乎没有设置背景pixbuf或其他图像格式的方法。

我正在Python中使用PyGTK,但任何语言与GTK绑定的答案是可以接受的。

gtkTreeView的样机与背景图像:基于钟博尔的建议

Mockup of GTK TreeView with background image

第一次尝试

,我试过如下:

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) 

在第一这似乎没有哈已经有任何影响,但是当在我的TreeView选择项目我观察到以下:背景的

​​

部分“示出了通过”时,选择的行。 (注意,我使用的是基于我的样机的背景图像,除了它有一些蓝色,用于测试目的)。

我再激活的清除TreeView控件的内容,并重绘我的GUI的一部分,并指出这一点:

Tiled background visible

但是只要我添加的东西到TreeView的背景消失,所以我仍然不确定这是否朝着正确的方向发展。

+0

是否填充树视图后调用treeview.show_all()使背景可见?此外,一个骇人的建议:因为选择一行可以使背景可见,请执行类似treeview.get_selection()。select_all()来选择所有行。 – 2011-03-22 19:34:34

+0

@Jong show_all()似乎没有效果。此外,除非整个TreeView已满,否则select_all()将无法显示背景,即使此界面不再适用于用户。 : -/ – 2011-03-22 21:33:48

回答

0

我怀疑由于每个单元格都有一个控制其外观的渲染器,因此您必须以某种方式修改逐个单元格的树形视图。

不管怎样,下面的代码可能是值得一试(未经测试的,不完整的代码):

# 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属性在PyGTK reference记录。

我不确定数组位置如何映射到窗口小部件状态。如果是同在C++中,这将是:

0 - STATE_NORMAL  
1 - STATE_ACTIVE  
2 - STATE_PRELIGHT 
3 - STATE_SELECTED 
4 - STATE_INSENSITIVE 
+0

感谢您的建议。不幸的是我尝试了这种方法,并没有任何明显的效果。我也尝试直接设置'bg_pixmap'值(而不是先复制样式并将其设置回小部件),但它也不起作用。我认为'bg_pixmap'只影响窗口背景可见的小部件,但'TreeView'小部件用白色填充覆盖窗口背景。 – 2011-03-21 21:54:04

+0

预计的种类。我在看到你的评论之前编辑了答案,表明这确实是一个很长的镜头。由于每个单元格都有一个可以改变外观的渲染器,所以暴力方法就是修改每个单元格的背景。除非有人对Gtk的内部工作有深入的了解,否则可以解决这个问题...... – 2011-03-21 22:02:12

+0

在进一步的调查中,我发现设置bg_pixmap属性确实有一些作用。我将bg_pixmap数组中的每个值都设置为我图像的像素图,并使选定行的选择颜色成为图像的一部分。有时图像甚至会以平铺的形式显示为背景,但只有在TreeView为空时。我会为我的问题添加屏幕截图。 – 2011-03-22 17:19:01

0

使用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); 

} 

它似乎也有可能通过添加设置到透明的背景:

background: none; 

到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"); 
} 

enter image description here