为啥 Gdk::Pixbufs 在 Gtk::TreeView 中不可见?

Posted

技术标签:

【中文标题】为啥 Gdk::Pixbufs 在 Gtk::TreeView 中不可见?【英文标题】:Why are Gdk::Pixbufs not visible in Gtk::TreeView?为什么 Gdk::Pixbufs 在 Gtk::TreeView 中不可见? 【发布时间】:2014-12-31 10:21:15 【问题描述】:

在花了很长时间寻找答案之后,我希望有人可以帮助我解决这个问题。我正在尝试在 Fedora 21 系统上使用 gtkmm(版本 3.14.0)和 glade(版本 3.18.3)来创建带有许多小图像的Gtk::TreeView/Gtk::ListStore。我可以轻松地将股票图标放在列表中,但添加 Gdk::Pixbuf 对象似乎出错了。未显示错误或警告消息,但未显示 Gdk::Pixbuf 图像。

为了说明问题,我创建了一个最小的工作示例(程序代码和最后包含的 glade 文件)。运行这个程序应该会打开一个带有Gtk::TreeView 和两个“gtk-apply”图标的小窗口。第一列应该是添加为Gdk::Pixbuf 的图标,第二列应该是股票图标。但是,当我运行程序时,第一列仍然是空的。没有编译或运行时错误或警告。

我的最终应用程序将显示一个大约 100 行和大约 35 列的矩阵,其中大部分是小图标,以便快速概览一个月中不同日子完成的活动。这些图标都不是股票图标。

额外信息:在使用调试器执行程序后,我发现Gtk::ListStore 的第一列需要gtkmm__GdkPixbuf 类型的数据。 row[cols.m_pb] = pb 行中pb 的类型是GdkPixbufGdkPixbuf 类型无法自动转换为 gtkmm__GdkPixbuf,导致值设置为 0 (NULL)。显然这并不能解决问题,但可能有助于解决问题。

感谢您的帮助和对 2015 年的良好祝愿, 维姆

这是 mwe.glade 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkAccelGroup" id="accelgroup1"/>
  <object class="GtkApplicationWindow" id="mainwindow">
    <property name="can_focus">False</property>
    <property name="show_menubar">False</property>
    <child>
      <object class="GtkGrid" id="mainbox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkTreeView" id="treattree">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="vexpand">True</property>
            <property name="hscroll_policy">natural</property>
            <property name="model">treatstore</property>
            <property name="rules_hint">True</property>
            <property name="search_column">0</property>
            <property name="fixed_height_mode">True</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="sel1"/>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="col1">
                <property name="sizing">fixed</property>
                <property name="fixed_width">32</property>
                <property name="title">1</property>
                <child>
                  <object class="GtkCellRendererPixbuf" id="cell1">
                    <property name="width">16</property>
                    <property name="height">16</property>
                  </object>
                  <attributes>
                    <attribute name="pixbuf">0</attribute>
                  </attributes>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="col2">
                <property name="sizing">fixed</property>
                <property name="fixed_width">32</property>
                <property name="title">2</property>
                <child>
                  <object class="GtkCellRendererPixbuf" id="cell2"/>
                  <attributes>
                    <attribute name="stock-id">1</attribute>
                  </attributes>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="left_attach">0</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkListStore" id="treatstore">
    <columns>
      <!-- column-name col1 -->
      <column type="GdkPixbuf"/>
      <!-- column-name col2 -->
      <column type="gchararray"/>
    </columns>
  </object>
</interface>

文件 mwe.cpp:

#include <gtkmm.h>

namespace ws

class App : public Gtk::Application

protected:
    App() : Gtk::Application("nl.mwe.mwe"), m_mainwindow(0)
    
    Glib::set_application_name("MWE");
    

public:
    static Glib::RefPtr<App> create(int &argc, char **&argv)
    
    return Glib::RefPtr<App>(new App());
    
    void init(Glib::RefPtr<Gtk::Builder> builder);
    int run()
    
    return Gtk::Application::run(*m_mainwindow);
    
private:
    Gtk::ApplicationWindow *m_mainwindow;
;

// Definition of the column references
class ModelColumns : public Gtk::TreeModelColumnRecord

public:
    ModelColumns()
    
    add(m_pb);
    add(m_stock);
    
    Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > m_pb;
    Gtk::TreeModelColumn<Glib::ustring> m_stock;
;
static ModelColumns col;

 // End namespace ws

/**
 * \brief   Initialize the app
 * \param[in]       builder The builder object
 *
 * Here is where the list store is populated with the Gdk::Pixbuf
 */
void ws::App::init(Glib::RefPtr<Gtk::Builder> builder)

    builder->get_widget("mainwindow", m_mainwindow);
    m_mainwindow->show();

    Glib::RefPtr<Gtk::ListStore> store =
    Glib::RefPtr<Gtk::ListStore>::cast_static(
        builder->get_object("treatstore"));

    Gtk::TreeModel::Row row = *store->append();

    // The line below loads the stock icon as a pixbuf.
    Glib::RefPtr<Gdk::Pixbuf> pb =
    Gtk::IconTheme::get_default()->load_icon("gtk-apply", 16);
    row[col.m_pb] = pb;

    row[col.m_stock] = "gtk-apply";


int main (int argc, char *argv[])

    Glib::RefPtr<ws::App> myapp = ws::App::create(argc, argv);
    Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create();
    builder->add_from_file("mwe.glade");
    myapp->init(builder);
    return myapp->run();

【问题讨论】:

我为此问题提交了错误报告 [bugzilla.gnome.org/show_bug.cgi?id=742637]. 【参考方案1】:

Extra Information中显示的类型中发现问题后 在问题部分,我决定手动创建商店。定义 的GtkListStore 已从林间空地文件中删除。 ws::App::init() 方法改为:

void ws::App::init(Glib::RefPtr<Gtk::Builder> builder)

    builder->get_widget("mainwindow", m_mainwindow);

    Gtk::TreeView *treeview = 0;
    builder->get_widget("treattree", treeview);

    Glib::RefPtr<Gtk::ListStore> store =
    Gtk::ListStore::create(col);
    treeview->set_model(store);

    Gtk::TreeModel::Row row = *store->append();

    // The line below loads the stock icon as a pixbuf.
    Glib::RefPtr<Gdk::Pixbuf> pb =
        Gtk::IconTheme::get_default()->load_icon("gtk-apply", 16);
    row[col.m_pb] = pb;

    row[col.m_stock] = "gtk-apply";
    m_mainwindow->show();

虽然这不像希望的那样灵活,但它确实解决了问题。

【讨论】:

以上是关于为啥 Gdk::Pixbufs 在 Gtk::TreeView 中不可见?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在参数周围使用 /*、*/ 以及为啥在提取数组长度时使用 >>>? [复制]

为啥 CoreGui Roblox 锁定在 DataModel 中,为啥受信任的用户不能使用 CoreScripts?

为啥 + 仅在客户端是 NaN?为啥不在 Node.js 中?

在执行语义分割任务时我应该减去图像均值吗?为啥或者为啥不?

为啥我们不能在 TypeScript 类中定义一个 const 字段,为啥静态只读不起作用?

为啥这个函数序言中没有“sub rsp”指令,为啥函数参数存储在负 rbp 偏移处?