2011-03-21 100 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