Почему Gdk::Pixbufs не видны в Gtk::TreeView?

Потратив долгое время на поиск ответа, я надеюсь, что кто-то может помочь мне с этой проблемой. Я пытаюсь использовать gtkmm (версия 3.14.0) и Glade (версия 3.18.3) в системе Fedora 21 для создания Gtk::TreeView/Gtk::ListStore с множеством маленьких изображений. Я могу легко поместить стандартные значки в список, но добавление Gdk::Pixbuf объектов, похоже, пойдет не так. Сообщения об ошибках или предупреждения не отображаются, но изображение Gdk::Pixbuf не отображается.

Чтобы показать проблему, я создал минимальный рабочий пример (код программы и файл Glade в конце). Запуск этой программы должен открыть маленькое окно с Gtk::TreeView с двумя значками "gtk-apply". В первом столбце должна быть добавлена ​​иконка как Gdk::Pixbuf, во втором столбце должна быть иконка стока. Однако, когда я запускаю программу, первый столбец остается пустым. Нет никаких ошибок компиляции или времени выполнения или предупреждений.

Мое финальное приложение будет отображать матрицу примерно из 100 строк и около 35 столбцов, состоящих в основном из крошечных значков, позволяющих быстро просмотреть действия, выполненные в разные дни месяца. Ни одна из этих иконок не будет стандартной.

Дополнительная информация. После выполнения программы с помощью отладчика я обнаружил, что первый столбец Gtk::ListStore требует данных типа gtkmm__GdkPixbuf. Тип pb в строке row[cols.m_pb] = pbGdkPixbuf. Тип GdkPixbuf не может быть автоматически преобразован в 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();
}

person sawims    schedule 31.12.2014    source источник
comment
Я подал отчет об ошибке для этой проблемы [bugzilla.gnome.org/show_bug.cgi? id=742637].   -  person sawims    schedule 09.01.2015


Ответы (1)


Обнаружив проблемы с типами, как показано в разделе Дополнительная информация вопроса, я решил создать магазин вручную. Определение GtkListStore было удалено из файла Glade. Метод 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();
}

Хотя это не так гибко, как хотелось бы, это решает проблему.

person sawims    schedule 03.01.2015