wxlistbox Arrays with CASE and SWITCH not working Topic is solved

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.
papayrus
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 204
Joined: Tue Jan 25, 2011 4:55 pm
Location: USA
Contact:

Post by papayrus » Sun Jan 30, 2011 4:13 pm

PB wrote:Have you checked out the Controls sample and wxListBox documentation as I advised you earlier? It would really save you a lot of time.
You should do something like this for starters, a real application should have much more, e.g. enable/disable a button if there's an item selected or not, doubleclick on an item acting as if default button was pressed etc.

Code: Select all

class ListBoxFrame : public wxFrame {
...
private:
...
   enum ListBoxIndices {
     LBI_RUN_NOTEPAD = 0,
     LBI_RUN_IE,
     LBI_SHOW_MSGBOX
   };
   wxListBox* m_pListBox;
...
};

ListBoxFrame::ListBoxFrame(...

...
   m_pListBox = new ...
   
   wxCHECK(m_pListBox->Append(_("Launch Notepad")) == LBI_RUN_NOTEPAD);
   wxCHECK(m_pListBox->Append(_("Launch Internet Explorer")) == LBI_RUN_IE);
   wxCHECK(m_pListBox->Append(_("Show a MessageBox")) == LBI_SHOW_MSGBOX);
...
}

void ListBoxFrame::OnButtonClick(wxCommandEvent& event)
{
    int idx = m_pListBox->GetSelection();
    if (idx == wxNOT_FOUND)
       return; // there's no item selected
    switch (idx) {
       case LBI_RUN_NOTEPAD:
           wxExecute("notepad.exe");  // just a dummy 
           break;
       case LBI_RUN_IE:
           wxExecute("iexplore.exe"); // just a dummy 
           break;
       case LBI_SHOW_MSGBOX:
           wxMessageBox( ...
           break;
       default:
           wxFAIL_MSG("Invalid index in ListBoxFrame::OnButtonClick"); 
    }
}
I have to admit that I always used user data in situations like this, never relied on string values (which can be localized) or list indices when I dealt with list controls.
Thank you for this I will work on it. I got it to do what I wanted to do basically and thats where I needed to start. This is extra and I am going to steal it from you. HAHA just kidding got to work on it now. Oh and by the way thank you for your help I can get this to work now that I actually know the basics of it.

papayrus
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 204
Joined: Tue Jan 25, 2011 4:55 pm
Location: USA
Contact:

Post by papayrus » Thu Feb 03, 2011 12:19 pm

PB wrote:Have you checked out the Controls sample and wxListBox documentation as I advised you earlier? It would really save you a lot of time.
You should do something like this for starters, a real application should have much more, e.g. enable/disable a button if there's an item selected or not, doubleclick on an item acting as if default button was pressed etc.

Code: Select all

class ListBoxFrame : public wxFrame {
...
private:
...
   enum ListBoxIndices {
     LBI_RUN_NOTEPAD = 0,
     LBI_RUN_IE,
     LBI_SHOW_MSGBOX
   };
   wxListBox* m_pListBox;
...
};

ListBoxFrame::ListBoxFrame(...

...
   m_pListBox = new ...
   
   wxCHECK(m_pListBox->Append(_("Launch Notepad")) == LBI_RUN_NOTEPAD);
   wxCHECK(m_pListBox->Append(_("Launch Internet Explorer")) == LBI_RUN_IE);
   wxCHECK(m_pListBox->Append(_("Show a MessageBox")) == LBI_SHOW_MSGBOX);
...
}

void ListBoxFrame::OnButtonClick(wxCommandEvent& event)
{
    int idx = m_pListBox->GetSelection();
    if (idx == wxNOT_FOUND)
       return; // there's no item selected
    switch (idx) {
       case LBI_RUN_NOTEPAD:
           wxExecute("notepad.exe");  // just a dummy 
           break;
       case LBI_RUN_IE:
           wxExecute("iexplore.exe"); // just a dummy 
           break;
       case LBI_SHOW_MSGBOX:
           wxMessageBox( ...
           break;
       default:
           wxFAIL_MSG("Invalid index in ListBoxFrame::OnButtonClick"); 
    }
}
I have to admit that I always used user data in situations like this, never relied on string values (which can be localized) or list indices when I dealt with list controls.
OK I did this and it worked with a button. Is this for a checkListBox because I had to remove the WXCheck parts to make it work with my plain ListBox? Also how come when I set it to auto sort it doesn't seem to obey. For example if I click the first appended and then click the button it launches the code i set in another appended? Basically it does not stay in proper order.

Also wxExecute is not working I just made them into wxMessgaeBox. I am using wxpack 2.8 with code blocks. Is this a good mix or is there a better set up?

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

Post by PB » Thu Feb 03, 2011 1:55 pm

papayrus wrote:OK I did this and it worked with a button. Is this for a checkListBox because I had to remove the WXCheck parts to make it work with my plain ListBox? Also how come when I set it to auto sort it doesn't seem to obey. For example if I click the first appended and then click the button it launches the code i set in another appended? Basically it does not stay in proper order.
I thought that from the code it's crystal clear that if you rely on the item index, the indices have to match the declared enum values. If you want to have (auto)sorted list control or generally speaking a list control when you don't know at compile time what order the items are going to be in, you have to either rely on the string values which is imo not the best way; or do what I suggested earlier, associate each item with client data - see docs for more. You can also keep your own list of list indices, but I think that's clumsy and bug-prone solution.
papayrus wrote: Also wxExecute is not working I just made them into wxMessgaeBox. I am using wxpack 2.8 with code blocks. Is this a good mix or is there a better set up?
1. Check the wxExecute documentation, I used those calls pretty much just as placeholders - see my comments in the source code.
2. I don't know, I just use Visual C++ 2008 Express and the trunk version of wxWidgets for my (so far) experiments.

papayrus
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 204
Joined: Tue Jan 25, 2011 4:55 pm
Location: USA
Contact:

Post by papayrus » Thu Feb 03, 2011 3:37 pm

PB wrote:
papayrus wrote:OK I did this and it worked with a button. Is this for a checkListBox because I had to remove the WXCheck parts to make it work with my plain ListBox? Also how come when I set it to auto sort it doesn't seem to obey. For example if I click the first appended and then click the button it launches the code i set in another appended? Basically it does not stay in proper order.
I thought that from the code it's crystal clear that if you rely on the item index, the indices have to match the declared enum values. If you want to have (auto)sorted list control or generally speaking a list control when you don't know at compile time what order the items are going to be in, you have to either rely on the string values which is imo not the best way; or do what I suggested earlier, associate each item with client data - see docs for more. You can also keep your own list of list indices, but I think that's clumsy and bug-prone solution.
papayrus wrote: Also wxExecute is not working I just made them into wxMessgaeBox. I am using wxpack 2.8 with code blocks. Is this a good mix or is there a better set up?
1. Check the wxExecute documentation, I used those calls pretty much just as placeholders - see my comments in the source code.
2. I don't know, I just use Visual C++ 2008 Express and the trunk version of wxWidgets for my (so far) experiments.

It works great and yes I do see how I can assign numbers in the enum indices part. Why did you put an =0 on the first one when it auto makes it the 0 index anyway? Also I changed my listbox to a checklist box. I want it to do something while it is checked and nothing when it is unchecked but I can't get it to work. I been through the examples and there's nothing there to show me how to do this. Here is my code. I have tried various other things too but this seems like the best way to show what I am trying to accomplish.

Code: Select all

void checkListFrame::OnCheckListBox1Toggled(wxCommandEvent& event)
{

        if ( !CheckListBox1->IsChecked() )

       int idx = event.GetInt();
    switch (idx) {
       case LBI_RUN_HELLO:
           wxMessageBox(_("hello"));  // just a dummy
           break;
       case LBI_RUN_BYE:
           wxMessageBox(_("bye")); // just a dummy
           break;
       case LBI_SHOW_FINE:
           wxMessageBox(_("fine"));
           break;
       default:
           wxFAIL_MSG("Invalid index in ListBoxFrame::CheckListBox1Toggled");
    }
    else
    wxMessageBox(_("Not checked for all"));
}

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

Post by PB » Thu Feb 03, 2011 7:09 pm

In the EVT_CHECKLISTBOX handler you do something like this to learn if the item that has just been toggled is checked in or not:

Code: Select all

if (!m_pListBox->IsChecked(event.GetInt())
   return;
... item whose index = event.GetInt() was checked, do something with this information
But I have a feeling that this is not what you want to do here. By any chance, don't you want to go through all the items and perform some action on those that are checked, let's say as a response to a button click?

Anyway, with code snippets from here, Controls and Widgets (which demonstrates a wxCheckListBox usage) samples and wxWidgets documentation you should have all the info needed to proceed in any direction you need.

papayrus
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 204
Joined: Tue Jan 25, 2011 4:55 pm
Location: USA
Contact:

Post by papayrus » Thu Feb 03, 2011 7:44 pm

PB wrote:In the EVT_CHECKLISTBOX handler you do something like this to learn if the item that has just been toggled is checked in or not:

Code: Select all

if (!m_pListBox->IsChecked(event.GetInt())
   return;
... item whose index = event.GetInt() was checked, do something with this information
But I have a feeling that this is not what you want to do here. By any chance, don't you want to go through all the items and perform some action on those that are checked, let's say as a response to a button click?

Anyway, with code snippets from here, Controls and Widgets (which demonstrates a wxCheckListBox usage) samples and wxWidgets documentation you should have all the info needed to proceed in any direction you need.
Yes what I am trying to do is go through a checklist of needed to do things after a windows install. Each checkbox would launch what i need to do next. I just find it annoying that when I uncheck it the checkbox response is the same as the checked response I would rather have it either do nothing or maybe pop up a message to remind me that I already did that. But I am not sure yet. I was thinking about just having each checkbox turn a color like green after it has been checked to let me know I already checked that one. I dont know what the best thing to do yet is I am experimenting and learning listboxes and checklist boxes so I am not always using single controls like buttons and checkboxes and radios.
For example my GUI now has 30 buttons on it. I want to replace those buttons with a checklistbox I think or a listbox maybe so I can lessen the space my code takes up and make my GUI smaller.

Actualy thats an interresting idea. I usually do things one step at a time but I think some of these things can be done all at the same time for example I could do microsoft updates at the same time as creating shortcuts at the same time as copying over my scanner files. Or would that not be good for the machine?

OK I switched my checklist box to multi and now none of the cases are working. Only working in single mode?

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

Post by PB » Thu Feb 03, 2011 10:11 pm

If I understand your purpose, you want to:
1. Collect some info from a user, who can select tasks he wants to perform. I think wxCheckListBox is good for this.
2. Once he sets his choices and confirms them you want to display a window showing which tasks have been already finished and which ones still have to be done. I believe such a list could be done with e.g. wxHTMLListBox - successfully finished tasks should have something like big green checkmark, failed ones red cross, a task in progress and tasks still waiting to be processed something else. There should be also something like "X out of Y tasks have been done" and if a task can take some time, a progress bar should also be displayed.
In another words, something like an installer/updater. I would probably do it using a wxWizard dialog - gather info on one page, show the progress on another, just as installers usually do.

As for whether it would be faster do some tasks in parallel or not - that depends on your application. From what you have written, it sounds the bottleneck might be a hard drive performance, as long as you're reading/writing to one drive I think you won't gain much if anything. In worst case it might take longer. Also no offense, but I don't think right now you're ready to tackle possible issues that can arise when synchronising multiple threads and processes.

As for multiple selection listboxes - what doesn't work? IsSelected() should work both for single and multiple selection listboxes. Of course GetSelection() won't work for multiple selection listboxes, you have to use GetSelections() to obtain all indices of selected items at once.

papayrus
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 204
Joined: Tue Jan 25, 2011 4:55 pm
Location: USA
Contact:

Post by papayrus » Fri Feb 04, 2011 2:04 pm

PB wrote:If I understand your purpose, you want to:
1. Collect some info from a user, who can select tasks he wants to perform. I think wxCheckListBox is good for this.
2. Once he sets his choices and confirms them you want to display a window showing which tasks have been already finished and which ones still have to be done. I believe such a list could be done with e.g. wxHTMLListBox - successfully finished tasks should have something like big green checkmark, failed ones red cross, a task in progress and tasks still waiting to be processed something else. There should be also something like "X out of Y tasks have been done" and if a task can take some time, a progress bar should also be displayed.
In another words, something like an installer/updater. I would probably do it using a wxWizard dialog - gather info on one page, show the progress on another, just as installers usually do.

As for whether it would be faster do some tasks in parallel or not - that depends on your application. From what you have written, it sounds the bottleneck might be a hard drive performance, as long as you're reading/writing to one drive I think you won't gain much if anything. In worst case it might take longer. Also no offense, but I don't think right now you're ready to tackle possible issues that can arise when synchronising multiple threads and processes.

As for multiple selection listboxes - what doesn't work? IsSelected() should work both for single and multiple selection listboxes. Of course GetSelection() won't work for multiple selection listboxes, you have to use GetSelections() to obtain all indices of selected items at once.
Yes I tried Getselections but there must be some other places in the code I need to change it as well. I get an ERROR something like. CANNOT ALLOCATE AN OBJECT OF ABSTRACT TYPE "wxListBox" I think the problem is in this code

Code: Select all

virtual void SetSelection(int n) = 0;
    virtual int GetSelection() const = 0;
And here is the code I made on the listBox.



Code: Select all

void ListBoxFrame::OnListBox1Select(wxCommandEvent& event)
{
    int idx = ListBox1->GetSelections();
    if (idx == wxNOT_FOUND)
       return; // there's no item selected
    switch (idx) {
       case LBI_RUN_HELLO:
           wxMessageBox(_("hello"));  // just a dummy
           break;
       case LBI_RUN_BYE:
           wxMessageBox(_("bye")); // just a dummy
           break;
       case LBI_SHOW_FINE:
           wxMessageBox(_("fine"));
           break;
       default:
           wxFAIL_MSG("Invalid index in ListBoxFrame::OnButton1Click");
    }

}
EDIT ITS OK
I just had to clean the project and it is ok now.

Post Reply