TreeView, построенный на поляне с gtkmm

У меня есть TreeView / ListStore, созданный на поляне, который я пытаюсь загрузить в приложение и манипулировать через gtkmm.

Вот класс менеджера:

typedef struct
{
Gtk::ListStore *liststore_info;
Gtk::TreeModelColumn<string> *treeview_info_column_time;
Gtk::TreeModelColumn<string> *treeview_info_column_message;
}UiElements;

class GuiManager
{
Glib::RefPtr<Gtk::Builder> builder;
UiElements elements;

public:
GuiManager();
~GuiManager();

void info_handler(string msg);
}

И реализация:

GuiManager::GuiManager()
{
builder = Gtk::Builder::create();
builder->add_from_file("GUI.glade");

builder->get_widget("liststore_info", elements.liststore_info);
builder->get_widget("treeview_info_column_time", elements.treeview_info_column_time);
builder->get_widget("treeview_info_column_message", elements.treeview_info_column_message);
}

Вот функция, которую я пытаюсь вызвать для управления TreeView:

void GuiManager::info_handler(string msg)
{
Gtk::TreeModel::Row row = *(elements.liststore_info->append());
row[*(elements.treeview_info_column_time)] = "Now";
row[*(elements.treeview_info_column_message)] = msg;
}

И наконец, соответствующий Glade XML:

<object class="GtkListStore" id="liststore_info">
<columns>
<!-- column-name Time -->
<column type="string"/>
<!-- column-name Message -->
<column type="string"/>
</columns>
</object>
<object class="GtkTreeView" id="treeview_info">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore_info</property>
<property name="enable_search">False</property>
<property name="enable_grid_lines">both</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeview_info_column_time">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="min_width">100</property>
<property name="title" translatable="yes">Time</property>
<property name="clickable">True</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeview_info_column_message">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="min_width">300</property>
<property name="title" translatable="yes">Message</property>
<property name="clickable">True</property>
</object>
</child>
</object>

Однако компиляция завершается неудачно со следующим:

In file included from /usr/include/gtkmm-3.0/gtkmm.h:119:0,
from GUI3_gui_manager.h:8,
from GUI3_gui_manager.cpp:1:
/usr/include/gtkmm-3.0/gtkmm/builder.h: In instantiation of ‘void Gtk::Builder::get_widget(const Glib::ustring&, T_Widget*&) [with T_Widget = Gtk::TreeModelColumn<std::basic_string<char> >]’:
GUI3_gui_manager.cpp:64:86:   required from here
/usr/include/gtkmm-3.0/gtkmm/builder.h:628:93: error: ‘get_base_type’ is     not a member of ‘Gtk::TreeModelColumn<std::basic_string<char> >’
widget = dynamic_cast<T_Widget*>(this->get_widget_checked(name, T_Widget::get_base_type()));
^

Я явно неправильно использую TreeModelColumn, но мой исходный учебник для этого метода (который на данный момент доказал свою надежность) все происходит аналогичным образом, поэтому я не могу найти правильный метод здесь.

Любая помощь приветствуется. знак равно

3

Решение

Я только что понял, как это сделать. Это немного хитроумно, так как вам нужно создать класс C ++, который соответствует типам в вашем файле .glade, но если они совпадают, вы получаете те же функции безопасности типов, что и при создании TreeView вручную.

class Cols: public Gtk::TreeModel::ColumnRecord {
public:
Cols() {
// This order must match the column order in the .glade file
this->add(this->colA);
this->add(this->colB);
this->add(this->colC);
}

// These types must match those for the model in the .glade file
Gtk::TreeModelColumn<Glib::ustring> colA;
Gtk::TreeModelColumn<Glib::ustring> colB;
Gtk::TreeModelColumn<Glib::ustring> colC;
};

...

// Get hold of the TreeView from the .glade file
Gtk::TreeView* tv = nullptr;
refBuilder->get_widget("treeview1", tv); // refBuilder is Gtk::Builder instance
assert(tv);

// Get hold of the ListStore model from the .glade file
auto items = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(
refBuilder->get_object("listmodel1")
);
assert(items);

Cols mycols;

// Populate tree view with items
auto row = *(items->append());
row[mycols.colA] = "Row 1 Col 1";
row[mycols.colB] = "Row 1 Col 2";

row = *(items->append());
row[mycols.colA] = "Row 2 Col 1";

Это работает Cols::Cols() добавление типобезопасных столбцов в том же порядке, что и файл .glade, чтобы индекс сохранялся в каждом из colX переменные соответствуют типу данных в соответствующем индексе в модели. Только не забудьте обновить код, если вы когда-нибудь измените порядок столбцов! Вы даже можете добавить некоторые элементы в TreeView в Glade, а затем добавить больше элементов в код, и все они будут отображаться вместе во время выполнения!

Из чтения документов похоже, что вы также можете использовать небезопасный тип set_value() функционировать, если вы хотите избежать создания Cols класс полностью, как это: (не проверено)

row.set_value(0, "value for first column");
row.set_value(1, "value for second column");

Документы предупреждают, что сбой может произойти, если тип данных не соответствует ожидаемому формату столбца, поэтому нужно приложить усилия для создания такого класса, как Cols вероятно стоит того.

3

Другие решения

Обычно вы не можете определить TreeModel (ListStore, TreeStore) в Glade при использовании gtkmm. Типы C (используемые в Glade) и C ++ слишком разные, и API C ++ со статической типизацией не может знать об определении TreeModel вашего glade-файла во время компиляции.

Кроме того, в вашем коде ваш treeview_info_column_time в вашем коде C ++ является Gtk :: TreeModelColumn<>. Ваше treeview_info_column_time в вашем файле Glade является GtkTreeViewColumn. Столбцы модели и столбцы вида — это очень разные вещи. Вы можете просто использовать get_widget (), чтобы превратить одно в другое.

Вы также пытаетесь использовать get_widget (), чтобы получить свой listtore_info TreeModel (ListStore). Но TreeModel не является виджетом. get_object () может работать, но я бы не стал пытаться определить модель в Glade. Учебник, на который вы ссылаетесь, тоже этого не делает.

0

По вопросам рекламы [email protected]