Setting and keeping focus on a widget? 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.
Post Reply
Dodle
Knows some wx things
Knows some wx things
Posts: 29
Joined: Fri Dec 26, 2008 11:21 am

Setting and keeping focus on a widget?

Post by Dodle »

I want the focus to be set on a particular widget and kept on that widget always. An example would be I have two buttons (buttonA and buttonB) on a panel. buttonB is set to have the focus. After pressing buttonA, the focus will still be on buttonB.

How can I accomplish this?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

I guess you could simply catch focus events on B. When a focus-lost (or whatever it's called) event is fired, make B request focus again.
Dodle
Knows some wx things
Knows some wx things
Posts: 29
Joined: Fri Dec 26, 2008 11:21 am

Post by Dodle »

I've tried the following, but my program crashes.

Code: Select all

#include <wx/wx.h>

class MainWindow : public wxFrame
{
    public: MainWindow(const wxString& title);
	
	void LoseFocus(wxFocusEvent& event);
	
	wxPanel *panel1;
	wxButton *buttonA;
	wxButton *buttonB;
	
	wxBoxSizer *v_sizer;
	wxBoxSizer *h_sizer;
};

MainWindow::MainWindow(const wxString& title)
    : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(200,100), 
	                        wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER|
                            wxRESIZE_BOX|wxMAXIMIZE_BOX))
{
	panel1 = new wxPanel(this, -1);
	
	buttonA = new wxButton(panel1, -1, wxT("A"));
	buttonB = new wxButton(panel1, -1, wxT("B"));
        
        buttonB->SetFocus();
	
	buttonB->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(MainWindow::LoseFocus));
	
	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(buttonA, 1, wxEXPAND);
	h_sizer->Add(buttonB, 1, wxEXPAND);
	
	v_sizer = new wxBoxSizer(wxVERTICAL);
	v_sizer->Add(h_sizer, 1, wxEXPAND);
	
	panel1->SetSizer(v_sizer);
	
	Center();
}

void MainWindow::LoseFocus(wxFocusEvent& event)
{
    buttonB->SetFocus();
}

class Calc : public wxApp
{
    public : virtual bool OnInit();
};

IMPLEMENT_APP(Calc)

bool Calc::OnInit()
{
    MainWindow *frame = new MainWindow(wxT("Calculator"));
	frame->Show(true);
	return true;
}
Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

Post by Muetdhiver »

Hello,

maybe I'm wrong but your program is crashing on the buttonB->SetFocus function ?

Supposing this, the explanation could be that the SetFocus is called on your object (buttonB) by the event but the object is not yet created in memory (constructor not executed).

To test this supposition, I would have done this thing:

1) You remove the buttonB as a member variable of MainWindow (as buttonA also, that leads to nothing...).
2) So you declare your button only locally but attached them to the main sizer as you done, and also you put identifiants to them:

Code: Select all

wxButton* buttonA = new wxButton(panel1, ID_BUTTONA, wxT("A"));
wxButton* buttonB = new wxButton(panel1, ID_BUTTONB, wxT("B"));
3) So, in the LoseFocus function you can retrieve the object by its own ID only if it exists:

Code: Select all

void MainWindow::LoseFocus(wxFocusEvent& event)
{
    wxButton*  buttonB = wxDynamicCast( FindWindowById( ID_BUTTONB), wxButton );
    if ( buttonB )
    {
       buttonB->SetFocus();
    }
}
You could try this, maybe it will not work too... :)

Good luck.
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

As Muetdhiver correctly pointed out, you didn't tell us where it crashes, which is not too helpful for us to help ;)
Dodle
Knows some wx things
Knows some wx things
Posts: 29
Joined: Fri Dec 26, 2008 11:21 am

Post by Dodle »

Yes it does crash at:

Code: Select all

buttonB->SetFocus()
I learned in ubuntuforums.org, to add:

Code: Select all

,Null ,this
to the end of my "Connect" line.

Code: Select all

#include <wx/wx.h>

class MainWindow : public wxFrame
{
    public: MainWindow(const wxString& title);
       
        void LoseFocus(wxEvent& event);
       
        wxPanel *panel1;
        wxButton *buttonA;
        wxButton *buttonB;
       
        wxBoxSizer *v_sizer;
        wxBoxSizer *h_sizer;
};

MainWindow::MainWindow(const wxString& title)
    : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(200,100),
                                wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER|
                            wxRESIZE_BOX|wxMAXIMIZE_BOX))
{
        panel1 = new wxPanel(this, -1);
        
        buttonA = new wxButton(panel1, -1, wxT("A"));
        buttonB = new wxButton(panel1, -1, wxT("B"));
        
        buttonB->SetFocus();
        
        buttonA->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxEventHandler(MainWindow::LoseFocus), NULL, this);
        buttonB->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxEventHandler(MainWindow::LoseFocus), NULL, this);
        
        h_sizer = new wxBoxSizer(wxHORIZONTAL);
        h_sizer->Add(buttonA, 1, wxEXPAND);
        h_sizer->Add(buttonB, 1, wxEXPAND);
        
        v_sizer = new wxBoxSizer(wxVERTICAL);
        v_sizer->Add(h_sizer, 1, wxEXPAND);
        
        panel1->SetSizer(v_sizer);
        
        Center();
}

void MainWindow::LoseFocus(wxEvent& event)
{
    buttonB->SetFocus();
}

class Calc : public wxApp
{
    public : virtual bool OnInit();
};

IMPLEMENT_APP(Calc)

bool Calc::OnInit()
{
    MainWindow *frame = new MainWindow(wxT("Calculator"));
        frame->Show(true);
        return true;
}
And I changed the wxFocusEvent to wxEvent.
Post Reply