[SOLVED] Re: builder gio::resource problem



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:

Hi Marty,

On 04/10/2017 04:26 AM, Marty Moore wrote:
Hi Aitor,
Thanks for you video. Unfortuantely, I have very little eyesight, and can't watch videos. Golld luck on your project though.

I fixed my compiler error. I had missed correcting the $(COM P_RES) error. I was re-reading the advice and found it again.

My example_builder project now compiles, and generates a large  resouce.c file.

Here's the compiler output:
make -k 
/usr/lib/x86_64-linux-gnu/glib-2.0/glib-compile-resources --target=resource.c --sourcedir=`pwd` --generate-source  gresource.xml

Compilation finished at Sun Apr  9 19:49:54

Unfortunately, I get the following run-time error:

main 0:
Error loading example_builder.ui: The resource at '/builder/example_builder.ui' does not exist

As i said, i changed:

builder->add_from_resource( ... );

by:

builder->add_from_file( ... );

On the other hand, there were some mistakes in the .glade file, i think. Download this one:

http://gnuinos.org/Example-Builder/src/example_builder.ui

My questions are:
1. Is /builder/example_vuilder.ui the correct name for the resource?
2. where does that name come from? There isn't an actual file with that name, but it seems like that's the way resources are named. Does it come out of the .xml file?

Sorry for the confusion with the makefile error.
Thanks from the mountains of SW Colorado,
Marty

You can call this file *.ui, *.glade or *.xml...

You can also include the code of this file in a *.cpp, for example:

https://developer.gnome.org/gtkmm-tutorial/stable/sec-menus-examples.html.en

Take a look at the lines:
Glib::ustring ui_info =
    "<interface>"
    "  <!-- menubar -->"
    "  <menu id='menu-example'>"
    "    <submenu>"

[ ... etc ...]

Cheers,

  Aitor.










[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]