Hi Aitor, It finally works! Thank you all for your help! It all boiled down to the makefile. It turns out that resouces need to be compiled twice, once by Glib::compile_resources, and again by g++. This was not clear in chapter 12.4 of "Programming with gtkmm", at least for dinosaurs like me. I suggest that chapter 12.4 be rewitten with more detail and examples of each stage of creating and loading gio::resources. I would also suggest that a complete, simple, and working example including a makefile be added to chapter 12.4. While not everyone uses makefile, it would be a simple reference for all users. The example of 12.5 don't work, because their focus in on menus, and some required pieces (.glade files, makefiles) are missing. Below are the final working parts of the example_window from gtkmm-3-18.1/demos/gtk-demo. Hopefully, I didn't make any typos.... I hope this help others trying to figure out how to use gio::resource. Thanks again for your help. Marty makefile: PKGS = gtkmm-3.0 INCL = `pkg-config --cflags $(PKGS)` LIBS = `pkg-config --libs $(PKGS)` COMP_RES = /usr/lib/x86_64-linux-gnu/glib-2.0/glib-compile-resources CC = g++ CFLAGS = -g -Wall $(INCL) EXE = x OBJS = example_builder.o resource.o DIR = `pwd` $(EXE): $(OBJS) $(CC) $(OBJS) $(LIBS) -o $(EXE) example_builder.o: example_builder.cc $(CC) $(CFLAGS) -c example_builder.cc resource.o: resource.c $(CC) $(INCL) -c resource.c -o resource.o resource.c: gresource.xml example_builder.ui $(COMP_RES) --target=$@ --sourcedir=$(DIR) --generate-source $< .phony: clean: rm *.o *~ *.h~ *.cc~ *.c *.c~ x gresources.xml: <?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/builder"> <file>example_builder.ui</file> </gresource> </gresources> example_builder.ui: <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <interface> <object class="GtkListStore" id="liststore1"> <columns> <column type="gchararray"/> <column type="gchararray"/> <column type="gint"/> <column type="gchararray"/> </columns> <data> example_builder.cc: // File: example_builder.cc // (from gtkmm-3.18.1/demos/gtkcemo) // main function added at end of file. /* Builder * * Demonstrates an interface loaded from a XML description. */ #include "gtkmm.h" #include "gtk/gtk.h" #include <iostream> // For std::cout using std::cout; using std::endl; class Example_Builder : public Gtk::Window { public: Example_Builder(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder); virtual ~Example_Builder(); protected: void on_file_quit(); void on_help_about(); void on_help_help(); Glib::RefPtr<Gtk::Builder> m_builder; }; //Called by DemoWindow: Gtk::Window* do_builder() { cout << "do_builder 0:" << endl; // Load the XML file and instantiate its widgets: Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create(); try { builder->add_from_resource( "/builder/example_builder.ui"); } catch (const Glib::Error& error) { std::cout << "Error loading example_builder.ui: " << error.what() << std::endl; return nullptr; } // Get the GtkBuilder-instantiated window: Example_Builder* pWindow = nullptr; builder->get_widget_derived("window1", pWindow); if (!pWindow) { std::cout << "Could not get 'window1' from the builder." << std::endl; return nullptr; } return pWindow; } Example_Builder::Example_Builder( BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder) : Gtk::Window(cobject), m_builder(builder) { Gtk::Toolbar* pToolbar = nullptr; builder->get_widget("toolbar1", pToolbar); if (pToolbar) pToolbar->get_style_context()->add_class("primary-toolbar"); Glib::RefPtr<Gio::SimpleActionGroup> refActions = Gio::SimpleActionGroup::create(); refActions->add_action("quit", sigc::mem_fun(*this, &Example_Builder::on_file_quit)); refActions->add_action("about", sigc::mem_fun(*this, &Example_Builder::on_help_about)); refActions->add_action("help", sigc::mem_fun(*this, &Example_Builder::on_help_help)); insert_action_group("win", refActions); Glib::RefPtr<Gtk::AccelGroup> refAccelGroup = Gtk::AccelGroup::create(); add_accel_group(refAccelGroup); Gtk::MenuItem* pMenuItem = nullptr; builder->get_widget("new_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_n, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("open_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_o, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("save_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_s, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("quit_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_q, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("copy_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_c, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("cut_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_x, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("paste_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_v, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); builder->get_widget("help_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_F1, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); builder->get_widget("about_item", pMenuItem); if (pMenuItem) pMenuItem->add_accelerator("activate", refAccelGroup, GDK_KEY_F7, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); show_all(); } Example_Builder::~Example_Builder() { } void Example_Builder::on_file_quit() { hide(); } void Example_Builder::on_help_about() { Gtk::AboutDialog* pDialog = nullptr; m_builder->get_widget("aboutdialog1", pDialog); if (pDialog) { pDialog->set_transient_for(*this); pDialog->run(); pDialog->hide(); } } void Example_Builder::on_help_help() { std::cout << "Help not available." << std::endl; } int main( int argc, char* argv[]) { cout << "main 0:" << endl; auto app = Gtk::Application::create( argc, argv); Gtk::Window* win = do_builder(); return app->run(*win); } // end of example_builder files. On Mon, 2017-04-10 at 09:20 +0200, aitor_czr wrote:
|