how to connect Gio::SimpleAction signal

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

how to connect Gio::SimpleAction signal

Marty  Moore
Hi all,
I've been trying to create a dynamic menu in gtkmm3, using the
Gio::MenuModel classes. I can get the Gtk::MenuButton to popup the
Gio::MenuItem, and the Item responds to the click. Unfortunately, I
can't figure out how to connect the Gio::SimpleAction to my signal
handler. The only example I can find is a Gtk+ one, and it uses
different functions.

The problem is thet the prototype for the signal connection is:
 void on_my_activate(const Glib::VariantBase& parameter)

I've tried various combinations, but I can't get the connection to
work. I don't know how to handle the VariantBase.

I'd appreciate a nudge in the right direction.
Thanks,
Marty

Here's my code:

xwin.h:
 

> #include <iostream>
> #include <gtkmm.h>
> #include <giomm/menu.h>
> #include <giomm/simpleaction.h>
>
>
> using std::cout;
> using std::endl;
>
> namespace geode
> {
>
>
>     class Gui : public Gtk::Window
>     {
>     public:
> Gui();
> virtual ~Gui();
>
> void create_cv_menu ();
>
>     protected:
> // void on_cv_menu_clicked( guint& index);
> // void on_cv_menu_clicked();
> // void on_cv_menu_clicked(guint& index);
> void on_cv_menu_clicked( guint& index)
> //     const Glib::Variant<guint32>& parameter)
>     { cout << "on_cv_clicked 0:" << endl; }
>
> //Child widgets:
> Gtk::Box m_Box;
> Glib::RefPtr<Gio::MenuModel> menumodel;
> Glib::RefPtr<Gio::Menu> giomenu;
> Gtk::MenuButton mbut1;
> Glib::RefPtr<Gio::SimpleAction> ref_action;
>     }; // end class Gui
>     
> } // end namespace geode
> #endif //GTKMM_EXAMPLEWINDOW_H

xwin.cpp:

#include "xwin.h"
#include <iostream>

namespace geode
{
    
//CCCCCC GUI CCCCCCCCCCCCCCCC
    Gui::Gui()
        : m_Box(Gtk::ORIENTATION_VERTICAL),
          mbut1()
    {
        set_title("menu test");
        set_default_size(200, 200);
        mbut1.set_label("button 1");
        add(m_Box);
        create_cv_menu();
        m_Box.pack_start(mbut1, Gtk::PACK_SHRINK, 5);
        mbut1.set_menu_model(menumodel);
        show_all_children();
    }

    Gui::~Gui()
    {
    }

    //FFFFFF GUI FFFFFFFFFFFFFFFF
    void Gui::create_cv_menu()
    {
        cout << "Gui create_cv_menu 0:" << endl;
        guint32 index = 1;
        giomenu = Gio::Menu::create();
        menumodel = giomenu;
        giomenu->append("FRONT");
        ref_action = Gio::SimpleAction::create("FRONT");
        ref_action->signal_activate().connect(
            sigc::bind<guint32>(
        sigc::mem_fun(*this, &Gui::on_cv_menu_clicked), index));

// this is Gio::SimpleAction signal_activate handler prototype
//    void on_my_activate(const Glib::VariantBase& parameter)

        cout << "Gui create_cv_menu 99:" << endl;
    }
/*
//FFFFFF GUI FFFFFFFFFFFFFFFF
    void Gui::on_cv_menu_clicked(const Glib::Variant<guint32>& index)
    {
        cout << "Gui on_cv_menu_clicked 0: index = " << index << endl;

// return true;
    }
*/
} // end namespace geode

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Daniel Boles
So what's the problem? Does it compile but not work? Do you get a compiler error? Or it works except  you don't know what to do with the argument?

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Daniel Boles
Anyway, if what you're trying to do is invoke an Action in your MenuItem click handler, shouldn't you just be using Gio::MenuItem.set_action() or .set_action_and_target(), and let GIO handle all that, instead of reinventing the wheel? Maybe I misunderstood, in which case, a clearer and step-by-step explanation of what you want to do would be good.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Marty  Moore
Hi Daniel,
Thanks for your reply.
Sorry that I wasn't clear. I've been trying to connect the signal using
the same method I've used before. I looked at set_action and target. Is
that the proper way to connect the MenuItem to my handler? Is target
the name/address of my handler? I wish I could have found an example.

The program doesn't compile. I get an error similar to:
error: no match for call to ‘(sigc::bound_mem_functor1<void,
geode::Gui, unsigned int&>) (const Glib::VariantBase&, unsigned int&)’

The actual error changes slightly depending on how I try to connect.

OK, I've been playing around with MenuItem::set_action and _target.
This is what I have so far:
ref_action = Gio::SimpleAction::create("FRONT");
        Glib::RefPtr<Gio::MenuItem> front_item =
Gio::MenuItem::create("FRONT", menumodel);
        front_item->set_action_and_target("ref_action",
Gui::on_cv_menu_clicked(index));
        giomenu->append("FRONT", "menumodel");

but this results in compiler error:
mber function ‘void geode::Gui::create_cv_menu()’:
xwin.cpp:36:80: error: invalid use of void expression
  front_item->set_action_and_target("ref_action",
Gui::on_cv_menu_clicked(index));
                  

I still don't understand what to do with the VariantBase target value
from:
void  set_action_and_target (const Glib::ustring& action, const
Glib::VariantBase& target_value)

There must be a way to tie the signal handler( on_cv_menu_clicked) to
the MenuItem and action, but I don't see it.
What is the target value supposed to be?

So much for my ramblings....
Thanks for any help you can provide.
Marty
On Thu, 2017-12-14 at 12:01 +0000, Daniel Boles wrote:

> Anyway, if what you're trying to do is invoke an Action in your
> MenuItem click handler, shouldn't you just be using
> Gio::MenuItem.set_action() or .set_action_and_target(), and let GIO
> handle all that, instead of reinventing the wheel? Maybe I
> misunderstood, in which case, a clearer and step-by-step explanation
> of what you want to do would be good.
>
> _______________________________________________
> gtkmm-list mailing list
> [hidden email]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Daniel Boles
The idea I have is that, rather than specifically handling a click on the menu item, you just set an action that is to be invoked whenever the menu item is activated.

Then GIO/GTK+ handle making clicks, pressing Enter, etc on the item invoke that action - so you don't have to worry about handling those low-level events manually.

So you won't be tying click handlers to actions or anything: you just set the action on the menu item, and then you get standard click/key handlers for free, which activate the action when the menu item is activated.

What you do with the VariantBase in the action callback is to cast it to whatever type you know it has. That is the type of your action and therefore your menu item: bool for toggles, int or string for radio actions, etc. So something like

void
on_action_activated(Glib::VariantBase const& variant)
{
  auto the_boolean = Glib::Variant<bool>::cast_dynamic(variant).get();
  do_something_with(the_boolean);
}

I don't have a more specific example to hand, but this is the general idea of how I would ahndle it.



_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Marty  Moore
Hi Daniel, Thanks for your replay.
I found two things while perusing the documentation:
1. I nedd to connect either the signal_activate or signal_state_changed
of the SimpleAction if I don't want default behavior.
2. There's a 'TODO' note saying that documentation is needed about how
to connect the signals.

I'm still playing around with things, but what I really need is a
tutorial about how to use Variant/BariantBase. I'm getting stuck every
time I run into it. There doesn't seem to be much explanation about
it. I assumed it was along the lines of void*, where you can use it for
any data type. Is there something to explain how to use it? A good
example about this stuff would really be appreciated.
Thanks for your help,
Marty


On Fri, 2017-12-15 at 10:08 +0000, Daniel Boles wrote:

> The idea I have is that, rather than specifically handling a click on
> the menu item, you just set an action that is to be invoked whenever
> the menu item is activated.
>
> Then GIO/GTK+ handle making clicks, pressing Enter, etc on the item
> invoke that action - so you don't have to worry about handling those
> low-level events manually.
>
> So you won't be tying click handlers to actions or anything: you just
> set the action on the menu item, and then you get standard click/key
> handlers for free, which activate the action when the menu item is
> activated.
>
> What you do with the VariantBase in the action callback is to cast it
> to whatever type you know it has. That is the type of your action and
> therefore your menu item: bool for toggles, int or string for radio
> actions, etc. So something like
>
> void
> on_action_activated(Glib::VariantBase const& variant)
> {
>   auto the_boolean =
> Glib::Variant<bool>::cast_dynamic(variant).get();
>   do_something_with(the_boolean);
> }
>
> I don't have a more specific example to hand, but this is the general
> idea of how I would ahndle it.
>
>
> _______________________________________________
> gtkmm-list mailing list
> [hidden email]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Kjell Ahlstedt-2

Have you looked at the menu examples in the gtkmm tutorial? One with a popup menu:
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus/popup?h=gtkmm-3-22

In that example the actions are inserted in a Gio::SimpleActionGroup. I think that a SimpleActionGroup would simplify your code. In the usual types of menu items (plain menu item, toggle menu item, radio menu item) you can connect signal handlers without a VariantBase parameter. Gio::SimpleActionGroup (actually its base class Gio::ActionMap) has several add_action*() methods for different types of menu items.

There are other examples with menus. They also use a SimpleActionGroup.
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus/main_menu?h=gtkmm-3-22
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus_and_toolbars?h=gtkmm-3-22

Kjell


On 2017-12-16 21:43, Marty Moore wrote:
Hi Daniel, Thanks for your replay.
I found two things while perusing the documentation:
1. I nedd to connect either the signal_activate or signal_state_changed
of the SimpleAction if I don't want default behavior.
2. There's a 'TODO' note saying that documentation is needed about how
to connect the signals.

I'm still playing around with things, but what I really need is a
tutorial about how to use Variant/BariantBase. I'm getting stuck every
time I run into it. There doesn't seem to be much explanation about
it. I assumed it was along the lines of void*, where you can use it for
any data type. Is there something to explain how to use it? A good
example about this stuff would really be appreciated.
Thanks for your help,
Marty




_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Marty  Moore
HappyOn Tue, 2017-12-19 at 10:02 +0100, Kjell Ahlstedt wrote:
> Have you looked at the menu examples in the gtkmm tutorial? One with
> a
Hapy new year all,
I have been working on this, without much accomplished. I have code
that compiles and runs, with the menu showing up, but can't get the
action to be activated when the menu itme is clicked.

AI'v also noticed that if I append a new menu item with only a label,
the menu item is enabled, but if I append a menu item with label and
action the menu item is disabled.

I haven't been able to avoid this situation. Any ideas??

Marty

code:

include "gui.h"
#include <iostream>

namespace geode
{
   
//CCCCCC GUI CCCCCCCCCCCCCCCC
    Gui::Gui()
        : m_Box(), //Gtk::ORIENTATION_VERTICAL),
          mbut1()
    {
        set_title("menu test");
        set_default_size(200, 200);
        mbut1.set_label("button 1");

        add(m_Box);
        m_Box.pack_start(mbut1);

        cout << "gui 0:" << endl;
        giomenu = Gio::Menu::create();
        menumodel = giomenu;
        gtkmenu = new Gtk::Menu( giomenu);

        cout << "gui 1:" << endl;
        act_group = Gio::SimpleActionGroup::create();
        act_group->add_action("FIRST",
                              sigc::mem_fun(*this, &Gui::on_action));
        act_group->add_action("SECOND",
                              sigc::mem_fun(*this, &Gui::on_action));
        act_group->add_action("THIRD",
                              sigc::mem_fun(*this, &Gui::on_action));

        cout << "gui 2:" << endl;
        giomenu->append("FIRST");
        giomenu->append("SECOND");
        giomenu->append( "THIRD", "THIRD");
       
        cout << "gui 3:" << endl;
        mbut1.set_menu(*gtkmenu);
        show_all();
    }

    Gui::~Gui()
    { }
} // end namespace geod

> popup menu:
> https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/m
> enus/popup?h=gtkmm-3-22
>
> In that example the actions are inserted in a Gio::SimpleActionGroup.
> I
> think that a SimpleActionGroup would simplify your code. In the
> usual
> types of menu items (plain menu item, toggle menu item, radio menu
> item)
> you can connect signal handlers without a VariantBase parameter.
> Gio::SimpleActionGroup (actually its base class Gio::ActionMap) has
> several add_action*() methods for different types of menu items.
>
> There are other examples with menus. They also use a
> SimpleActionGroup.
> https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/m
> enus/main_menu?h=gtkmm-3-22
> https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/m
> enus_and_toolbars?h=gtkmm-3-22
>
> Kjell
>
>
> On 2017-12-16 21:43, Marty Moore wrote:
> > Hi Daniel, Thanks for your replay.
> > I found two things while perusing the documentation:
> > 1. I nedd to connect either the signal_activate or
> signal_state_changed
> > of the SimpleAction if I don't want default behavior.
> > 2. There's a 'TODO' note saying that documentation is needed about
> how
> > to connect the signals.
> >
> > I'm still playing around with things, but what I really need is a
> > tutorial about how to use Variant/BariantBase. I'm getting stuck
> every
> > time I run into it. There doesn't seem to be much explanation about
> > it. I assumed it was along the lines of void*, where you can use it
> for
> > any data type. Is there something to explain how to use it? A good
> > example about this stuff would really be appreciated.
> > Thanks for your help,
> > Marty
> >
> >
>
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Daniel Boles
> if I append a menu item with label and action the menu item is disabled.

I think that indicates the action you tried to set on the menuitem was not found, so it gets desensitised (normally it'd be sensitised according to whether the action is enabled, but obviously...)

I don't know what "act_group" is, but when I see this problem, it's usually because of not prepending app. or win. to the action name. In some contexts, like this, you need to use the detailed action name, i.e. the prefix of the map (app or win) followed by a period and then the simple action name.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: how to connect Gio::SimpleAction signal

Kjell Ahlstedt-2
If your menu is not a window menu or application menu, the prefix can
something else, not necessarily win or app. Comparing your code with
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus/popup?h=gtkmm-3-22 
I see that you have not called Gtk::Widget::insert_action_group(). An
example:

insert_action_group("myactiongroup", act_group);

Then the call to giomenu->append() should be

giomenu->append("THIRD", "myactiongroup.THIRD");


Den 2018-01-02 kl. 18:45, skrev Daniel Boles:

> > if I append a menu item with label and action the menu item is disabled.
>
> I think that indicates the action you tried to set on the menuitem was
> not found, so it gets desensitised (normally it'd be sensitised
> according to whether the action is enabled, but obviously...)
>
> I don't know what "act_group" is, but when I see this problem, it's
> usually because of not prepending app. or win. to the action name. In
> some contexts, like this, you need to use the detailed action name,
> i.e. the prefix of the map (app or win) followed by a period and then
> the simple action name.
>
>

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list