问题
I am trying to keep a std::vector
of Gtk::Widget
s that I am showing (and will potentially be) moving around between Gtk::Container
s.
At the moment I keep a Gtk::Notebook
which is basically a one-to-one map to the std::vector
, but if I use Glib::RefPtr
around the widgets I get problems when removing the widget from the notebook. I already have to use a 'hack' to get a pointer to the underlying Gtk object when adding it to the notebook and I suspect that the Notebook container frees/deletes the object when I remove it from the container.
I have defined my vector of widgets something like this:
std::vector<Glib::RefPtr<Gtk::Widget>> widgets;
When I add a widget to the vector and the notebook I do:
Glib::RefPtr<Gtk::Widget> w (new Gtk::Widget());
widgets.push_back (w);
Gtk::Widget *wptr = w.operator->(); // hack
notebook.append_page (*wptr);
when I try to remove it I do:
int c = 1; // widget no. to remove
notebook.remove_page (c);
auto it = widgets.begin() + c;
widgets.erase (it);
but this results in a G_IS_OBJECT
fail assertion when (I think) the element in the std::vector
is cleaned up at the end of the iterator
(end of function), since possibly notebook.remove_page()
already freed the object. How can I do this? Is it possible with RefPtr
's?
Related (same assertion failure): Destructing Glib::RefPtr causes failed assertions in the GTK 3 core
回答1:
Unfortunately you can't do this because the Gtk::Notebook
takes ownership of the child objects. You have to refactor your code to use the Gtk::Notebook
itself to access the widgets instead of the vector
, for example with Gtk::Notebook::get_nth_page().
回答2:
Glib::RefPtr<> should not be used with widgets. It is not a general purpose smartpointer. It should only be used with classes that force you to use it - by having no public constructor but having public create*() methods.
来源:https://stackoverflow.com/questions/22373506/gtkmm-using-refptr-with-widgets-kept-in-stdvector