如何向 GTK TreeView 添加背景图像?

发布于 2024-10-24 07:56:59 字数 1153 浏览 9 评论 0 原文

我想要一个带有背景图像的 GTK TreeView,如下面的模型所示。

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

我将 Python 与 PyGTK 结合使用,但使用 GTK 绑定的任何语言的答案都是可以接受的。

带有背景图像的 gtkTreeView 模型

带有背景图像的 GTK TreeView 模型

第一次尝试

根据 Jong Bor 的建议,我尝试了以下操作:

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 中选择一个项目后,我观察到以下内容:

显示部分背景图像的选定行

当选择一行时,部分背景“显示出来”。

(请注意,我使用的是基于我的模型的背景图像,但出于测试目的,它有一些蓝色)。

然后,我激活了 GUI 的一部分,用于清除 TreeView 的内容并重新绘制它,并观察到这一点:

Tiled backgroundvisible

但是一旦我向 TreeView 添加一些内容,背景就会消失,所以我仍然不确定这是否朝着正确的方向发展。

I would like to to have a GTK TreeView with a background image as shown in the mockup below.

I have found methods for setting the background color of widgets, but there does not appear to be a method for setting a background pixbuf or other image format.

I'm using Python with PyGTK but an answer in any language with GTK bindings is acceptable.

Mockup of gtkTreeView with background image:

Mockup of GTK TreeView with background image

First Attempt

Based on Jong Bor's advice, I tried the following:

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)

At first this didn't seem to have any effect, but upon selecting an item in my TreeView I observed the following:

Selected row showing part of the background image

Part of the background 'shows through' when a row is selected.

(Note that I'm using a background image based on my mockup, except that it has some blue color, for test purposes).

I then activated part of my GUI that clears the contents of the TreeView and redraws it, and observed this:

Tiled background visible

However as soon as I add something to the TreeView the background disappears, so I'm still not sure if this is going in the right direction.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天旳寂寞 2024-10-31 07:56:59

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

无论如何,以下代码可能值得一试(未经测试、不完整的代码):

# 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 参考

我不确定数组位置如何映射到小部件状态。如果与c++中的相同,则为:

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

I suspect that since each cell has a renderer which controls its appearance, you would have to somehow modify the treeview cell by cell.

Anyway, the following code might be worth a try (untested, incomplete code):

# 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)

The bg_pixmap attribute is documented in the PyGTK reference.

I'm not sure of how the array positions map to widget states. If it is the same as in c++, it will be:

0 - STATE_NORMAL    
1 - STATE_ACTIVE    
2 - STATE_PRELIGHT  
3 - STATE_SELECTED  
4 - STATE_INSENSITIVE   
二智少女 2024-10-31 07:56:59

使用 GTK3 和 gtkmm 可以使用 CSS,但图像需要作为文件或可能作为资源提供。

这里我假设树视图是子类化的:

class MyTreeView : public Gtk::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");
}

在此处输入图像描述

Using GTK3 and gtkmm it is possible to use CSS, but the image needs to available as a file or possibly a resources.

Here I assume that the treeview is subclassed:

class MyTreeView : public Gtk::TreeView { .. };

for you treeview set a name and then add a CSS style to it:

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

}

it seems that it is also possible to set the background of the row to transparent by adding:

background: none;

to the CSS.

The background image can then be hidden or shown using:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文