on_remove not called



I'm having a problem subclassing Gtk::Container (or Gtk:Bin, the same results). Please consider the sample source code attached.

I encounter some problems when my container class is destroyed. For some reason, on_remove() is never called, and I get a gtk error message. The output of the code is the following, for just running the code, and closing the window:

./sample
MyBin::on_add
MyBin::forall_vfunc
MyBin::forall_vfunc
MyBin::forall_vfunc
MyBin::on_size_request
MyBin::on_size_allocate
MyBin::forall_vfunc
MyBin::forall_vfunc
MyBin::forall_vfunc
MyBin::forall_vfunc
end of run
MyWindow::~MyWindow
MyBin::~MyBin

(sample:18459): Gtk-CRITICAL **: gtk_container_remove: assertion `GTK_IS_CONTAINER (container)' failed
out of block



it's visible that at the destruction of MyBin, something goes wrong. also, on_remove never seems to be called..

I just can't figure out what I'm doing wrong, as the sample code you'll see is extremely similar to the custom widget sample provided with gtk--.

any suggestions?
#include <iostream>
#include <gtkmm.h>

class MyBin : public Gtk::Container
{
    public:
        Gtk::Widget   * child;

        MyBin(void);

        virtual
        ~MyBin(void)
        {
            std::cerr << "MyBin::~MyBin" << std::endl;
        }

        virtual void
        on_add(Gtk::Widget* child);

        virtual void
        on_remove(Gtk::Widget* child);

        void
        forall_vfunc(gboolean    includeInternals,
                     GtkCallback callback,
                     gpointer    callbackData);

        void
        on_size_request(Gtk::Requisition *requisition);

        void
        on_size_allocate(Gtk::Allocation& allocation);

        GtkType
        child_type_vfunc(void) const;
};

MyBin :: MyBin(void)
{  
    set_flags(Gtk::NO_WINDOW);
    set_redraw_on_allocate(false);
    child = 0;
}

void
MyBin :: on_size_request(Gtk::Requisition* requisition)
{
    std::cerr << "MyBin::on_size_request" << std::endl;
    *requisition = Gtk::Requisition();

    if (child) {
        Gtk::Requisition  childRequisition = child->size_request();
        requisition->width  = childRequisition.width;
        requisition->height = childRequisition.height;
    } else {
        requisition->width  = 10;
        requisition->height = 10;
    }
}

void
MyBin :: on_size_allocate(Gtk::Allocation& allocation)
{
    std::cerr << "MyBin::on_size_allocate" << std::endl;
    set_allocation(allocation);

    if (child) {
        child->size_allocate(allocation);
    }

    Gtk::Container::on_size_allocate(allocation);
}

void
MyBin :: forall_vfunc(gboolean    includeInternals,
                      GtkCallback callback,
                      gpointer    callbackData)
{
    std::cerr << "MyBin::forall_vfunc" << std::endl;
    if (child) {
        callback(child->gobj(), callbackData);
    }
}

GtkType
MyBin :: child_type_vfunc(void) const
{
    std::cerr << "MyBin::child_type_vfunc" << std::endl;
    return child ? G_TYPE_NONE : Gtk::Widget::get_type();
}

void
MyBin :: on_add(Gtk::Widget* child)
{
    std::cerr << "MyBin::on_add" << std::endl;
    if (!this->child) {
        this->child = child;
        this->child->set_parent(*this);
    }
}

void
MyBin :: on_remove(Gtk::Widget* child)
{
    std::cerr << "MyBin::on_remove" << std::endl;
    if (this->child == child) {
        this->child = 0;
        bool visible = child->is_visible();
        child->unparent();
        if (visible) {
            queue_resize();
        }
    }
}



class MyWindow : public Gtk::Window
{
    public:
        Gtk::Label  label;
        MyBin       bin;

        MyWindow(void);

        virtual
        ~MyWindow(void)
        {
            std::cerr << "MyWindow::~MyWindow" << std::endl;
        }
};


MyWindow :: MyWindow(void)
                : label("Hello, World!")
{
    bin.add(label);
    add(bin);
    show_all();
}


int main(int argc, char *argv[])
{
    Gtk::Main   kit(argc, argv);

    {
        MyWindow    myWindow;
        Gtk::Main::run(myWindow);
        std::cerr << "end of run" << std::endl;
    }
    std::cerr << "out of block" << std::endl;

    return 0;
}

all: sample

CXXFLAGS=`pkg-config --cflags "gtkmm-2.4 >= 2.4.0"`
LDFLAGS=`pkg-config --libs "gtkmm-2.4 >= 2.4.0"`

sample: sample.o
	g++ ${LDFLAGS} -o sample sample.o

sample.o: sample.cxx
	g++ ${CXXFLAGS} -o sample.o -c sample.cxx

clean:
	rm -f sample.o sample

run:
	./sample


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