Trying to catch the enter-key in a KEY_EVT from a wxListBox

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.
svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Trying to catch the enter-key in a KEY_EVT from a wxListBox

Post by svearike » Fri Feb 10, 2006 12:50 am

Hi,
I'm trying to catch the enter-key when a wxListBox is in focus.
I do:

Code: Select all

wxListBox *box = new wxListBox......
box->Connect( ... EVT_CHAR ....
and all the other keys are caught..
even TAB (had to pass wxWANTS_CHARS to a couple of windows.
but still, no enter.


the layout is like this

wxPopupTransientWindow -> wxPanel -> wxListBox

is it not possible to catch the enter key from a wxListBox ?
that seems a bit, well, odd ?

/Tommy

sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson » Fri Feb 10, 2006 1:23 am

Try something like this.

Code: Select all

box->Connect(wxID_ANY, wxEVT_COMMAND_ENTER, wxCommandEventHandler(YourListBox::YourEnterFunc));

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Fri Feb 10, 2006 1:30 am

sethjackson wrote:Try something like this.

Code: Select all

box->Connect(wxID_ANY, wxEVT_COMMAND_ENTER, wxCommandEventHandler(YourListBox::YourEnterFunc));
I'm sorry to inform you that it didn't work :(
Any other ideas ? I did like this:

Code: Select all

   list->Connect(wxEVT_COMMAND_ENTER,
                 wxCommandEventHandler(SimpleTransientPopup::OnEnter),
                 NULL, this);

sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson » Fri Feb 10, 2006 1:33 am

You need to supply Connect with an ID.

Code: Select all

list->Connect(wxID_ANY, wxEVT_COMMAND_ENTER,
                    wxCommandEventHandler(SimpleTransientPopup::OnEnter),                 );
Also, could you post some more code related to the listbox? What are you trying to do? Catch the enter key???

EDIT:

Why are you passing this to connect?

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Fri Feb 10, 2006 1:43 am

I'm passing this to connect because I experienced problems before when using connect, omitting the this pointer would make the this-pointer of the object calling the eventfunction equal to the list-pointer (list->Connect).
So I just figured , put this in there :) and it worked

I've never really put wxID_ANY in there and it has worked on everything else, just connecting the widgets of my choosing.

But I tried it your way aswell, didn't work :/

There isn't really much more code around the listbox, it's just a ordinary:

Code: Select all

list = new wxListBox(m_panel,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxArrayString(),wxWANTS_CHARS|wxLB_SORT|wxLB_SINGLE);
plus a Connect()

and a event function that all it does is: printf("OnEnter\n");

sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson » Fri Feb 10, 2006 1:44 am

Waaait a sec I think I have it.

Your layout is like this

wxPopupTransientWindow -> wxPanel -> wxListBox

You use Connect() like this.

Code: Select all

list->Connect(wxEVT_COMMAND_ENTER,
                 wxCommandEventHandler(SimpleTransientPopup::OnEnter),
                 NULL, this);
I assume SimpleTransientPopup is the wxPopupTransientWindow?

Then that is why Connect() fails.

Code: Select all

void Connect(int id, wxEventType eventType, wxObjectEventFunction function, wxObject* userData = NULL, wxEvtHandler* eventSink = NULL)
eventSink

Object whose member function should be called. If this is NULL, this will be used.

You are passing Connect() the wrong object. :)

Code: Select all

list->Connect(wxEVT_COMMAND_ENTER,
                 wxCommandEventHandler(SimpleTransientPopup::OnEnter),
                 NULL, SimpleTransientPopupObj);

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Fri Feb 10, 2006 1:47 am

Code: Select all

list->Connect(wxEVT_COMMAND_ENTER,
                 wxCommandEventHandler(SimpleTransientPopup::OnEnter),
                 NULL, SimpleTransientPopupObj);
The thing is, this = my SimpleTransientPopupObj :\
the connect is done in the constructor of SimpleTransient.....
and the event function is also in the same class..
so it gets the correct this-value (or did I misinterpret something?)

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Fri Feb 10, 2006 2:21 am

This is really frustrating.

Code: Select all

list->Connect(EVT_CHAR.... );
that code catches the ENTER if I press fn + ENTER (using a laptop). which I assume is the same thing as using the NUMPAD ENTER.
But NOT the ENTER.. Why ?!

I didn't think it was possible to write a event that would deny the programmar to later on add his own event-function ABOVE the old one ?
But it looks like that's what's being done here ?
I can't catch the event of ENTER being pressed.

nor does it post a EVT_COMMAND_ENTER event afterwards.

sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson » Fri Feb 10, 2006 2:28 am

Yes you are right. I'm shooting in the dark here, but maybe you could try this.

Code: Select all

list->Connect(wxEVT_KEY_DOWN,
                 wxKeyEventHandler(SimpleTransientPopup::OnEnter),
                 NULL, this);

void SimpleTransientPopup::OnEnter(wxKeyEvent& event)
{
    if (event.GetKeyCode() == WXK_RETURN)
    {
        // Do stuff.
    }
}

http://www.wxwidgets.org/manuals/2.6.2/ ... getkeycode

I think WXK_RETURN is the Enter key. Here is the list of virtual key codes.

http://www.wxwidgets.org/manuals/2.6.2/ ... l#keycodes

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Fri Feb 10, 2006 2:39 am

First of all, thank you for all your help.

Secondly.. :(
I've already tried that.
EVT_KEY_DOWN
EVT_CHAR
EVT_KEY_UP
EVT_COMMAND_ENTER
you name it, been there done that.. actually I have them ALL on atm :)
and none of them even REACT on normal ENTER :\

I "solved" the problem by putting in almost every function
m_panel->SetFocusIgnoringChildren();
and now it works, but that really seems like a cruel hack :)
The documentation even states that this function is rarely needed, hehe
If I could get it to work in a more satisfying way that would be great :)

DavidHart
Site Admin
Site Admin
Posts: 4005
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Fri Feb 10, 2006 11:21 am

Hi,

IIRC You are using wxGTK. src/gtk/listbox.cpp contains:

Code: Select all

    if ((gdk_event->keyval == GDK_Return) && (!ret))
    {
        // eat return in all modes
        ret = TRUE;
    }
Perhaps the idea is to stop Enter triggering a wxEVT_COMMAND_LISTBOX_SELECTED event.

I think your only hope is to push a new event handler onto the listbox. I expect this would be able to process Enter before the above code could swallow it.

Regards,

David

svearike
Experienced Solver
Experienced Solver
Posts: 57
Joined: Tue Jan 31, 2006 3:08 pm

Post by svearike » Sat Feb 11, 2006 6:57 pm

Ah okey, well that explains why it disappears.
But I'm still a bit confused with the internals of event/eventhandler.
What do you mean with pushing a new eventhandler ?
I thougt that was what I was doing when ->Connect() ? or is that "pushing a new event" ..

Any example code? :)

DavidHart
Site Admin
Site Admin
Posts: 4005
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Sat Feb 11, 2006 11:36 pm

I thougt that was what I was doing when ->Connect() ? or is that "pushing a new event"
Sorry, I've no idea. I almost never use Connect().

This is an untested adaptation of a bit of my code. As you can see, it's easier than it sounds.

Code: Select all

class MyEvtHandler : public wxEvtHandler
{
void ProcessEvent(wxKeyEvent& event);
  DECLARE_EVENT_TABLE()
};

void MyEvtHandler::ProcessEvent(wxKeyEvent& event)
{
// Check for Enter and do something if it is
event.Skip();
}

BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
	EVT_KEY_DOWN(wxID_ANY, MyEvtHandler::ProcessEvent )
END_EVENT_TABLE()
You may need to use EVT_COMMAND_ENTER or EVT_CHAR instead or as well. I've left you to test for Enter and do something if it is.

Then when you have created your listbox, do this immediately after:
list->PushEventHandler(new MyEvtHandler);

Hope it works.

David

Mampfred
Knows some wx things
Knows some wx things
Posts: 26
Joined: Tue Aug 31, 2004 2:28 pm
Location: Germany
Contact:

Post by Mampfred » Sat Aug 11, 2007 2:42 pm

*bump*

I'm having exactly the same problem and still can't find a way to solve this. Only difference: I'm using wxMSW. Any chance someone can have anoher look at this?

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Thu Aug 13, 2009 7:22 am

Mampfred wrote:*bump*

I'm having exactly the same problem and still can't find a way to solve this. Only difference: I'm using wxMSW. Any chance someone can have anoher look at this?
Simply set your wxListBox control style with wxWANTS_CHARS should work.This has been asked in another thread and has been tested.

Code: Select all

wxListBox* yourListbox=new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0|wxWANTS_CHARS ); 
  

void keydownAppDialog::onListBoxKeyDown(wxKeyEvent& event) 
{ 
    if( event.GetKeyCode()==WXK_RETURN) 
    { 
        wxMessageBox(_T("Return key pressed."),_T("Capture key press event.")); 
    } 
    else
   {
        event.Skip();
   }
} 
  
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

Post Reply