Glib::RefPtr

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

Glib::RefPtr

Phil Wolff-3
To quote the tutorial on Glib::RefPtr, "unlike most smartpointers, you
can't use the * operator to access the underlying instance." Is there
some other way to make a copy of the underlying object?

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

Re: Glib::RefPtr

Daniel Boles
Well, there is always operator->() ...

but what kind of object are you wanting to copy? There's a good chance it doesn't have the right semantics for that. Most mm objects are not copyable, just movable. (And most GObjects aren't copyable either; properties are not the only state they hold.)



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

Re: Glib::RefPtr

Phil Wolff-2
I'd like to use FlowBox::bind_list_store() in a photo-management
application by building a set of ListStore<T_item> for the contents of
each of several folders on a remote system (a time-consuming process),
and then choosing which to display by binding the appropriate model.
Problem is, when I try to bind a model that has previously been bound
and then unbound (again quoting the documentation "If this FlowBox was
already bound to a Gio::ListModel, that previous binding is
destroyed."), I find that it's not just the binding that was destroyed,
but the widgets within the model's <T_item>s are destroyed as well. I'd
like to be able to copy the model (which is behind a RefPtr) and bind
the copy, thereby avoiding having to rebuild the model each time I want
to reuse it.

Actually, if I could serialize/deserialize the model a la
Gtk::TextBuffer, that might also work. Is that doable?


On 10/08/2017 06:29 AM, Daniel Boles wrote:

> Well, there is always operator->() ...
>
> but what kind of object are you wanting to copy? There's a good chance
> it doesn't have the right semantics for that. Most mm objects are not
> copyable, just movable. (And most GObjects aren't copyable either;
> properties are not the only state they hold.)
>
>
>
>
> _______________________________________________
> 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: Glib::RefPtr

Daniel Boles
If you want to keep the models around, then you should keep a RefPtr to them around, so that you hold an extra reference to stop them being destroyed.

FlowBox should only destroy the binding, not the model itself; if the latter occurs, it must be a result of you not having kept a reference to the model to keep it alive.

Or did I misunderstand?


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

Re: Glib::RefPtr

Phil Wolff-2
My T_item is:

class CObject : public Glib::Object
{
public:
     static Glib::RefPtr<CObject > create ( const Glib::ustring& );
     virtual         ~CObject ();
     ...
protected:
     explicit        CObject ( const Glib::ustring& );
private:
     ...
     Gtk::Frame*     m_pFrame;
     ...
};

The string argument is the name of the photo file, and the Frame
contains the display built from the information in the photo file.

Creating the model:.

     m_refSpecificModel = Gio::ListStore<CObject >::create ( filename );

Binding:

     m_refCurrentModel = m_refSpecificModel;
     m_pFlowBox->bind_list_store ( m_refCurrentModel, ... );

All m_* variables are members of the executing class and therefore do
not go out of scope. I don't see why m_refSpecificModel's reference
count should go to 0.

When I try to re-bind the model, the CObject instances are still present
in m_refSpecificModel and the value of each m_pFrame is unchanged, but
m_pFrame->gobj () returns 0.

On 10/08/2017 06:50 AM, Daniel Boles wrote:

> If you want to keep the models around, then you should keep a RefPtr
> to them around, so that you hold an extra reference to stop them being
> destroyed.
>
> FlowBox should only destroy the binding, not the model itself; if the
> latter occurs, it must be a result of you not having kept a reference
> to the model to keep it alive.
>
> Or did I misunderstand?
>
>
>
> _______________________________________________
> gtkmm-list mailing list
> [hidden email]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list

--
It is better to have tried and failed than to have failed to try, but
the result's the same.
    — Mike Dennison
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Glib::RefPtr

Daniel Boles
How do you create m_pFrame, and what do you do with it between creating it and finding it to be 0?

It sounds to be like you might be Gtk::manage()ing it and then adding it to a container, in which case, that container sinks the floating reference and takes over ownership completely. If so, you'd need to not do that; have it as a non-pointer member and just hand out observing references/pointers to it.


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

Re: Glib::RefPtr

Phil Wolff-2
     CObject::CObject ( const Glib::ustring& filename )
     {
         m_pFrame = (Gtk::Frame*)( new CThumbnail ( filename ) );
     }

     Gtk::Frame* CObject::GetFrame ()
     {
         return ( m_pFrame );
     }

Elsewhere,

     class CThumbnail : public Gtk::Frame
     {
     ...
     };

I have neglected to mention the slot argument:

     m_pFlowBox->bind_list_store ( m_refCurrentModel, sigc::mem_fun (
*this, &CBridge::OnContentCreate () ) );
     ...
     Gtk::Widget* CBridge::OnContentCreate ( const Glib::RefPtr<CObject
 >& refObject )
     {
         return ( (Gtk::Widget*)refObject->GetFrame () );
     }

m_pFrame is stored in the CObject constructor, and retrieved for the
return value of the callback slot, it is otherwise untouched in the
application.

I construct two models and bind the first, and everything goes as
expected. When I then bind the second model, all is still well. But when
I bind the first model again, I get a bunch of failed assertions and a
blank display.

I also constructed a much simpler example using Gtk::Label in place of
Gtk::Frame and CThumbnail (which does contain Gtk::manage() calls) and

     m_pLabel = new Gtk::Label (filename);

in the CObject constructor. The results are the same.

On 10/08/2017 07:47 AM, Daniel Boles wrote:

> How do you create m_pFrame, and what do you do with it between
> creating it and finding it to be 0?
>
> It sounds to be like you might be Gtk::manage()ing it and then adding
> it to a container, in which case, that container sinks the floating
> reference and takes over ownership completely. If so, you'd need to
> not do that; have it as a non-pointer member and just hand out
> observing references/pointers to it.
>
>
>
> _______________________________________________
> gtkmm-list mailing list
> [hidden email]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list

--
It is better to have tried and failed than to have failed to try, but
the result's the same.
    — Mike Dennison
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Glib::RefPtr

Daniel Boles

On 8 October 2017 at 16:59, Phil Wolff <[hidden email]> wrote:
I have neglected to mention the slot argument:

    m_pFlowBox->bind_list_store ( m_refCurrentModel, sigc::mem_fun ( *this, &CBridge::OnContentCreate () ) );

For clarity: the invalid function call () on the pointer-to-method is not in the real code. :)


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

Re: Glib::RefPtr

Daniel Boles
I've taken a look at this and think it's intentional and fairly clear:
  • GTK+ and gtkmm both refer to the slot as "a slot that creates widgets". i.e. creates, for the FlowBox's consumption. Not a slot that returns a reference to a widget that already existed for some other purpose.
  • GtkFlowBox does   gtk_flow_box_forall (GTK_CONTAINER (box), FALSE, (GtkCallback) gtk_widget_destroy, NULL);

So, I think your original conclusion, that the widgets must always be rebuilt, was correct.

As for the question about copying them, I'm afraid that can't work, as far as I know; relatively few GObjects maintain all their state as properties, often keeping essential info in private structs, so unless the C class provides a copy/clone method, that can't be done. Not that I think it'd help much here anyway - you'd just be copying instead of deleting/recreating.

Perhaps you can instead build all the FlowBoxes, one for each model, then just show the one that's currently relevant. e.g. using Gtk::Stack



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

Re: Glib::RefPtr

Phil Wolff-2
Bad news, 'cause rebuilding is really slow, and copying or serializing
would be much faster.

I wasn't paying much attention to the callback because it didn't appear
to be the problem, but modifying the example accordingly does effect a cure.

I have used Gtk::Stack in another application, but I had completely
forgotten it. I'll give it a shot.

Thanks for the assist!

On 10/08/2017 09:30 AM, Daniel Boles wrote:

> I've taken a look at this and think it's intentional and fairly clear:
>
>   * GTK+ and gtkmm both refer to the slot as "a slot that creates
>     widgets". i.e. creates, for the FlowBox's consumption. Not a slot
>     that returns a reference to a widget that already existed for some
>     other purpose.
>   * GtkFlowBox does   gtk_flow_box_forall (GTK_CONTAINER (box), FALSE,
>     (GtkCallback) gtk_widget_destroy, NULL);
>
> So, I think your original conclusion, that the widgets must always be
> rebuilt, was correct.
>
> As for the question about copying them, I'm afraid that can't work, as
> far as I know; relatively few GObjects maintain all their state as
> properties, often keeping essential info in private structs, so unless
> the C class provides a copy/clone method, that can't be done. Not that
> I think it'd help much here anyway - you'd just be copying instead of
> deleting/recreating.
>
> Perhaps you can instead build all the FlowBoxes, one for each model,
> then just show the one that's currently relevant. e.g. using Gtk::Stack
>
>
>
>
> _______________________________________________
> gtkmm-list mailing list
> [hidden email]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list

--
It is better to have tried and failed than to have failed to try, but
the result's the same.
    — Mike Dennison
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Glib::RefPtr

Daniel Boles
Cool, hope you figure out something that works!


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

Re: Glib::RefPtr

Daniel Boles
I suppose another option is that you would setup all the widgets you need, manually add them to the FlowBox (no model-binding), and update their attributes as you detect changes in the model. It could be very manual, but maybe worth it if performance is otherwise less than you want to accept.


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