GridCellEditor: event handler assertion on exit

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
AUser
Knows some wx things
Knows some wx things
Posts: 38
Joined: Mon Jun 26, 2006 12:18 am

GridCellEditor: event handler assertion on exit

Post by AUser » Sun Nov 18, 2012 9:51 pm

Hello,

Im trying to track down an assertion error that occurs in wx2.9, under (at least) gtk and OSX. Apparently, I have not correctly destroyed my object, and I get the message:

Code: Select all

./src/common/wincmn.cpp(468): assert "GetEventHandler() == this" failed in ~wxWindowBase() : any pushed event handlers must have been removed
with stacktrace, which clearly shows something wrong in the (still existing) combo box generated by the wxGridCellChoiceEditor

Code: Select all

(and boring stuff)
#36 0x00007ffff62181c2 in wxOnAssert(char const*, int, char const*, char const*, wchar_t const*) () from /usr/local/lib/libwx_baseu-2.9.so.4
#37 0x00007ffff6e4e3d7 in wxWindowBase::~wxWindowBase() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#38 0x00007ffff6d01ef0 in wxWindow::~wxWindow() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#39 0x00007ffff6d98187 in wxControlBase::~wxControlBase() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#40 0x00007ffff6d379af in wxChoice::~wxChoice() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#41 0x00007ffff7b50ae2 in wxComboBox::~wxComboBox() ()
---Type <return> to continue, or q <return> to quit---
   from /usr/local/lib/libwx_gtk2u_xrc-2.9.so.4
#42 0x00007ffff6e507f3 in wxWindowBase::Destroy() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#43 0x00007ffff6e5081c in wxWindowBase::DestroyChildren() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#44 0x00007ffff6d01df6 in wxWindow::~wxWindow() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#45 0x00007ffff7337147 in wxGridWindow::~wxGridWindow() ()
   from /usr/local/lib/libwx_gtk2u_adv-2.9.so.4
#46 0x00007ffff6e507f3 in wxWindowBase::Destroy() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#47 0x00007ffff6e5081c in wxWindowBase::DestroyChildren() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#48 0x00007ffff6d01df6 in wxWindow::~wxWindow() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#49 0x000000000040fac4 in wxDerivedGrid::~wxDerivedGrid() ()
#50 0x000000000040fb00 in wxDerivedGrid::~wxDerivedGrid() ()
#51 0x00007ffff6e507f3 in wxWindowBase::Destroy() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#52 0x00007ffff6e5081c in wxWindowBase::DestroyChildren() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#53 0x00007ffff6d01df6 in wxWindow::~wxWindow() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#54 0x00007ffff6cf3982 in wxTopLevelWindowGTK::~wxTopLevelWindowGTK() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#55 0x00007ffff6dce8b9 in wxFrameBase::~wxFrameBase() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#56 0x000000000040f4e3 in MyFrame::~MyFrame() ()
#57 0x000000000040f516 in MyFrame::~MyFrame() ()
---Type <return> to continue, or q <return> to quit---
#58 0x00007ffff6215377 in wxAppConsoleBase::DeletePendingObjects() ()
   from /usr/local/lib/libwx_baseu-2.9.so.4
#59 0x00007ffff62153ed in wxAppConsoleBase::ProcessIdle() ()
   from /usr/local/lib/libwx_baseu-2.9.so.4
#60 0x00007ffff6d7f181 in wxAppBase::ProcessIdle() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#61 0x00007ffff6cd34a5 in wxApp::DoIdle() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#62 0x00007ffff6cd35c3 in wxapp_idle_callback ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#63 0x00007ffff2c75355 in g_main_context_dispatch ()
   from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#64 0x00007ffff2c75688 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#65 0x00007ffff2c75a82 in g_main_loop_run ()
   from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#66 0x00007ffff4f57797 in gtk_main ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#67 0x00007ffff6ce56fa in wxGUIEventLoop::Run() ()
   from /usr/local/lib/libwx_gtk2u_core-2.9.so.4
#68 0x00007ffff6218731 in wxAppConsoleBase::MainLoop() ()
   from /usr/local/lib/libwx_baseu-2.9.so.4
#69 0x00007ffff62949a5 in wxEntry(int&, wchar_t**) ()
   from /usr/local/lib/libwx_baseu-2.9.so.4
#70 0x000000000040ccbd in main ()
Ive minimised the code down to the following:

wxderivedgrid.h:

Code: Select all

#include <wx/wx.h>
#include <wx/grid.h>

class wxDerivedGrid : public wxGrid
{
	public:
		wxDerivedGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, 
					const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS);
		~wxDerivedGrid();
		
		//!Cause grid to layout some elemenets 
		void valueLayout();

		DECLARE_EVENT_TABLE()
};
wxderivedgrid.cpp:

Code: Select all


#include "wxderivedgrid.h"

BEGIN_EVENT_TABLE(wxDerivedGrid, wxGrid)
END_EVENT_TABLE()


wxDerivedGrid::wxDerivedGrid(wxWindow* parent, wxWindowID id, 
		const wxPoint& pos , const wxSize& size , long style ) :
					wxGrid(parent, id, pos, size , style)
{
}

wxDerivedGrid::~wxDerivedGrid()
{
}


//Layout the grid
void wxDerivedGrid::valueLayout()
{
	this->BeginBatch();

	//Empty the grid
	if(this->GetNumberCols())
		this->DeleteCols(0,this->GetNumberCols());
	if(this->GetNumberRows())
		this->DeleteRows(0,this->GetNumberRows());
	this->AppendCols(2);
	
	this->AppendRows(1);

	//Set the cell renderer
	wxGridCellAttr *attr = this->GetOrCreateCellAttr(0, 1);
	//construct a wxStringArray of possible choices.
	wxArrayString a;
	a.Add(_("Option 1"));
	a.Add(_("Option 2"));
	//Set up the editor
	wxGridCellChoiceEditor *choiceEd=new wxGridCellChoiceEditor(a);
	this->SetCellEditor(0,1,choiceEd);


	EndBatch();

}
myFrame.cpp:

Code: Select all


#include <wx/wx.h>
#include <wx/grid.h>

#include "wxderivedgrid.h"


class MyFrame: public wxFrame {
public:
    MyFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE);

private:
    void set_properties();
    void do_layout();

protected:
    wxDerivedGrid* mainGrid;
    
    DECLARE_EVENT_TABLE();

public:
    virtual void OnCellLeft(wxGridEvent &event); 
}; 



MyFrame::MyFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE)
{
    mainGrid = new wxDerivedGrid(this, wxID_ANY);

    set_properties();
    do_layout();

    mainGrid->valueLayout();

}


BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_GRID_CMD_CELL_LEFT_DCLICK(wxID_ANY, MyFrame::OnCellLeft)
END_EVENT_TABLE();


void MyFrame::OnCellLeft(wxGridEvent &event)
{
}


void MyFrame::set_properties()
{
    SetTitle(wxT("myFrame"));
    mainGrid->CreateGrid(10, 3);
}


void MyFrame::do_layout()
{

    wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
    sizer_1->Add(mainGrid, 1, wxEXPAND, 0);
    SetSizer(sizer_1);
    sizer_1->Fit(this);
    Layout();

}



class MyApp: public wxApp {
public:
    bool OnInit();
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    MyFrame* myFrame = new MyFrame(NULL, wxID_ANY, wxEmptyString);
    SetTopWindow(myFrame);
    myFrame->Show();
    return true;
}

Does anyone know why there is a leftover event handler? I've not asked (explicitly) for one. How do I fix this? ive tried getting the renderer back and calling decref, as well as resetting the default renderer in the destructor, but this changes it from an assert to a hard segfault. Any ideas would be really appreciated!

bcteh
Experienced Solver
Experienced Solver
Posts: 72
Joined: Mon Nov 27, 2006 9:56 am

Re: GridCellEditor: event handler assertion on exit

Post by bcteh » Thu Nov 22, 2012 5:34 pm

Something related to
wxGridCellAttr *attr = this->GetOrCreateCellAttr(0, 1);

attr->DecRef(); --> add this

theory i don't know [-X .. i faced the same error before

Post Reply