Delete an item from wxListCtrl.

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.
dkaip
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 202
Joined: Wed Jan 20, 2010 1:15 pm

Delete an item from wxListCtrl.

Postby dkaip » Sat Sep 15, 2018 1:15 pm

Hello in code bellow i am trying to delete items from wxListCtrl, but i take an error on OnSelectItem, last line.
The pos i of item is ok.
../include/wx/dynarray.h(838): assert "uiIndex < m_nCount" failed in Item().

Thank you
Jim.

Code: Select all

TextDrop::TextDrop(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(900, 600))
{

    wxSplitterWindow *spl1 = new wxSplitterWindow(this, -1);
    wxSplitterWindow *spl2 = new wxSplitterWindow(spl1, -1);
    m_gdir = new wxGenericDirCtrl(spl1, -1, wxT("/home/"),wxPoint(-1, -1), wxSize(50, 50), wxDIRCTRL_DIR_ONLY);

    m_lc1 = new wxListCtrl(spl2, -1, wxPoint(50, 50),wxSize(50, 50), wxLC_LIST);
    m_lc2 = new wxListCtrl(spl2, -1, wxPoint(50, 50),wxSize(50, 50), wxLC_LIST);

    MyTextDropTarget *mdt = new MyTextDropTarget(m_lc2);
    m_lc2->SetDropTarget(mdt);

    Connect(m_lc1->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG,wxListEventHandler(TextDrop::OnDragInit));

    wxTreeCtrl *tree = m_gdir->GetTreeCtrl();

    spl2->SplitHorizontally(m_lc1, m_lc2);
    spl1->SplitVertically(m_gdir, spl2);

    Connect(tree->GetId(), wxEVT_COMMAND_TREE_SEL_CHANGED,wxCommandEventHandler(TextDrop::OnSelect));
    Connect(m_lc2->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED,wxListEventHandler(TextDrop::OnSelectItem));

    Center();
}
MyTextDropTarget::MyTextDropTarget(wxListCtrl *owner)
{
    m_owner = owner;
}

bool MyTextDropTarget::OnDropText(wxCoord x, wxCoord y,const wxString& data)
{
    m_owner->InsertItem(0, data);
    return true;
}

void TextDrop::OnSelectItem(wxListEvent& event)
{
    wxListItem it=event.GetItem();
    long i=it.GetId();
//    m_lc2->DeleteItem(i);
    m_lc2->DeleteAllItems();
}

User avatar
doublemax
Moderator
Moderator
Posts: 12748
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Delete an item from wxListCtrl.

Postby doublemax » Sat Sep 15, 2018 5:56 pm

I assume the line that causes the problem is:

Code: Select all

m_lc2->DeleteItem(i);
and not the other one?

The assert message is clear: The item index is bigger too big and exceeds last item in the control. Check the values of "i" and "m_lc2->GetItemCount".
Use the source, Luke!

dkaip
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 202
Joined: Wed Jan 20, 2010 1:15 pm

Re: Delete an item from wxListCtrl.

Postby dkaip » Sun Sep 16, 2018 4:31 am

Yes this is line with problem.
I assume the line that causes the problem is:
m_lc2->DeleteItem(i);


Supposse m_lc2 has 2 objects, and click to first i take i=0 and j=2.
But i<j and proplem is the same.
Is problem of library? I use wxWidgets3.0.3 stable.
Even using DeleteAllItems () i have the same problem, so must be in library?
Thank you
Jim

Code: Select all

    wxListItem it=event.GetItem();
    long i=it.GetId();
    int j=m_lc2->GetItemCount();
    m_lc2->DeleteItem(i);

User avatar
doublemax
Moderator
Moderator
Posts: 12748
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Delete an item from wxListCtrl.

Postby doublemax » Sun Sep 16, 2018 8:10 am

Even using DeleteAllItems () i have the same problem, so must be in library?
Very unlikely, there must be something elso going on.

Please try to create a minimal, compilable sample that shows the problem.
Use the source, Luke!

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1734
Joined: Sun Jan 03, 2010 5:45 pm

Re: Delete an item from wxListCtrl.

Postby PB » Sun Sep 16, 2018 10:34 am

Using the simple code below it basically (did not test how multiple selection works) seems to work as expected( git master, MSW)

Code: Select all

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

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(NULL, wxID_ANY, "Test", wxDefaultPosition, wxSize(600, 400))
    {                               
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);       

        m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);       
        for ( int i = 0; i < 20; ++i )
            m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), wxString::Format("Item %d", i));           
        m_listCtrl->Bind(wxEVT_COMMAND_LIST_ITEM_SELECTED, &MyFrame::OnItemSelected, this);
        mainSizer->Add(m_listCtrl, wxSizerFlags().Expand().Proportion(3).Border(wxALL, 10));

         wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
            wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);       
        mainSizer->Add(logCtrl, wxSizerFlags().Expand().Proportion(1).Border(wxALL, 10));
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));     
                           
        SetSizer(mainSizer);         
    }   
private:
    wxListCtrl* m_listCtrl;

    void OnItemSelected(wxListEvent& evt)
    {       
        const long itemId = evt.GetItem().GetId();       

        wxASSERT(itemId == evt.GetIndex());
       
        wxLogMessage("OnItemSelected(): itemId = %ld, item count = %ld",
            itemId, m_listCtrl->GetItemCount());

        m_listCtrl->DeleteItem(itemId);
    }
};

class MyApp : public wxApp
{
public:   
   bool OnInit()
   {
        (new MyFrame)->Show();
        return true;
   }
}; wxIMPLEMENT_APP(MyApp);

dkaip
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 202
Joined: Wed Jan 20, 2010 1:15 pm

Re: Delete an item from wxListCtrl.

Postby dkaip » Sun Sep 16, 2018 11:21 am

Hello.
I upload the code, is from zetcode example.
Thank you
Jim
Attachments
drag and drop.zip
(1.73 KiB) Downloaded 6 times

dkaip
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 202
Joined: Wed Jan 20, 2010 1:15 pm

Re: Delete an item from wxListCtrl.

Postby dkaip » Sun Sep 16, 2018 11:27 am

For PB code i take error when pick an item...
Is library's bug?
/usr/include/wx-3.0/wx/strvararg.h(456): assert "(argtype & (wxFormatStringSpecifier<T>::value)) == argtype" failed in wxArgNormalizer(): format specifier doesn't match argument type

But when disable code

Code: Select all

//        wxLogMessage("OnItemSelected(): itemId = %ld, item count = %ld",
//            itemId, m_listCtrl->GetItemCount());

on item click item delete. But when click on last item i take error ...
../include/wx/dynarray.h(838): assert "uiIndex < m_nCount" failed in Item().

No drag and drop operation happens.
Thank you
Jim

User avatar
doublemax
Moderator
Moderator
Posts: 12748
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Delete an item from wxListCtrl.

Postby doublemax » Sun Sep 16, 2018 12:49 pm

I upload the code, is from zetcode example.

Under Windows i don't see any crash with your code. I can't test under Linux.
Use the source, Luke!

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1734
Joined: Sun Jan 03, 2010 5:45 pm

Re: Delete an item from wxListCtrl.

Postby PB » Sun Sep 16, 2018 1:24 pm

dkaip wrote:For PB code i take error when pick an item...
Is library's bug?
/usr/include/wx-3.0/wx/strvararg.h(456): assert "(argtype & (wxFormatStringSpecifier<T>::value)) == argtype" failed in wxArgNormalizer(): format specifier doesn't match argument type

But when disable code

Code: Select all

//        wxLogMessage("OnItemSelected(): itemId = %ld, item count = %ld",
//            itemId, m_listCtrl->GetItemCount());


This may be because GetItemCount() returns int and therefore the second printf specifier should be "%d" and not "%ld" (on my platform there is not difference between int and long). But as you said, this has no relation to the issue in question...

dkaip
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 202
Joined: Wed Jan 20, 2010 1:15 pm

Re: Delete an item from wxListCtrl.

Postby dkaip » Sun Sep 16, 2018 9:38 pm

In Linux wxWidgets lib must have problem.
It must works on both OS.
Thank you
Jim.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1734
Joined: Sun Jan 03, 2010 5:45 pm

Re: Delete an item from wxListCtrl.

Postby PB » Mon Sep 17, 2018 5:39 am

While it does not seem very likely, perhaps deleting the item in the OnSelect event handler may be an issue. Try doing it with CallAfter instead, e.g. like this

Code: Select all

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

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(NULL, wxID_ANY, "Test", wxDefaultPosition, wxSize(600, 400))
    {                               
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);       

        m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);       
        for ( int i = 0; i < 5; ++i )
            m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), wxString::Format("Item %d", i));           
        m_listCtrl->Bind(wxEVT_COMMAND_LIST_ITEM_SELECTED, &MyFrame::OnItemSelected, this);
        mainSizer->Add(m_listCtrl, wxSizerFlags().Expand().Proportion(3).Border(wxALL, 10));

         wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
            wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);       
        mainSizer->Add(logCtrl, wxSizerFlags().Expand().Proportion(1).Border(wxALL, 10));
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));     
                           
        SetSizer(mainSizer);         
    }   
private:
    wxListCtrl* m_listCtrl;

    void DeleteListCtrlItem(long item)
    {
        wxLogMessage("DeleteListCtrlItem(): item = %ld, item count = %d", item, m_listCtrl->GetItemCount());
        m_listCtrl->DeleteItem(item);
    }

    void OnItemSelected(wxListEvent& evt)
    {       
        const long itemId = evt.GetItem().GetId();       

        wxASSERT(itemId == evt.GetIndex());
       
        wxLogMessage("OnItemSelected(): itemId = %ld, item count = %d", itemId, m_listCtrl->GetItemCount());
        CallAfter(&MyFrame::DeleteListCtrlItem, itemId);
    }
};

class MyApp : public wxApp
{
public:   
   bool OnInit()
   {
        (new MyFrame)->Show();
        return true;
   }
}; wxIMPLEMENT_APP(MyApp);


Return to “C++ Development”

Who is online

Users browsing this forum: No registered users and 25 guests