wxFrame does not process Tab button - c++

I have a simple wxFrame with 3 buttons. After I press Tab nothing happens. In the forum I found that wxFrame should process Tab button events normally and switch focus between controls. I tried with wxTAB_TRAVERSAL and without it, but look like no result.
Here is my code. wxWidgets 3.0.2. Please, help.
class TabWnd
: public wxFrame
{
public:
TabWnd()
: wxFrame(nullptr,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL)
{
wxBoxSizer* sz = new wxBoxSizer(wxVERTICAL);
wxButton* b1 = new wxButton(this, wxID_ANY, wxT("First"));
sz->Add(b1, 0, wxALL, 5);
wxButton* b2 = new wxButton(this, wxID_ANY, wxT("Second"));
sz->Add(b2, 0, wxALL, 5);
wxButton* b3 = new wxButton(this, wxID_ANY, wxT("Third"));
sz->Add(b3, 0, wxALL, 5);
SetSizer(sz);
Layout();
Centre(wxBOTH);
}
};
class WxguiApp
: public wxApp
{
public:
bool OnInit() override
{
TabWnd* mainWnd = new TabWnd();
mainWnd->Show();
SetTopWindow(mainWnd);
return true;
}
};
IMPLEMENT_APP(WxguiApp);

Try adding a panel between the frame and the buttons like this:
wxBoxSizer* sz = new wxBoxSizer(wxVERTICAL);
wxPanel* pnl = new wxPanel( this, wxID_ANY );
wxBoxSizer* sz2 = new wxBoxSizer( wxVERTICAL );
wxButton* b1 = new wxButton(pnl, wxID_ANY, wxT("First"));
sz2->Add(b1, 0, wxALL, 5);
wxButton* b2 = new wxButton(pnl, wxID_ANY, wxT("Second"));
sz2->Add(b2, 0, wxALL, 5);
wxButton* b3 = new wxButton(pnl, wxID_ANY, wxT("Third"));
sz2->Add(b3, 0, wxALL, 5);
pnl->SetSizer( sz2 );
sz->Add( pnl, 1, wxEXPAND );
SetSizer(sz);
Layout();
Centre(wxBOTH);

Related

Size wxDialogs so all of the text is inside the Dialog

My wxWidgets program should work on both desktop PC and Windows tablet. Both use Windows 10 Pro 64-bit version. How can I make it, that a text with a changing size is inside a dialog no matter where it is displayed?
This is what I do now:
TrackDialog::TrackDialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,
const wxSize& size)
{
//(*Initialize(TrackDialog)
wxBoxSizer* BoxSizer4;
wxBoxSizer* BoxSizer5;
wxBoxSizer* BoxSizer2;
wxBoxSizer* BoxSizer1;
wxBoxSizer* BoxSizer3;
wxBoxSizer* pPanelSizer;
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP|wxSUNKEN_BORDER, _T("wxID_ANY"));
Panel1 = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
pPanelSizer = new wxBoxSizer(wxVERTICAL);
BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
StaticSelectText = new wxStaticText(Panel1, ID_STATICTEXT1, _("Select a *.xml file."), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
BoxSizer1->Add(StaticSelectText, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
XmlFilePickerCtrl = new wxFilePickerCtrl(Panel1, ID_FILEPICKERCTRL1, _T("./resources/"), wxEmptyString, _T("*.xml"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL, wxDefaultValidator, _T("ID_FILEPICKERCTRL1"));
BoxSizer2->Add(XmlFilePickerCtrl, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
StaticNumberText = new wxStaticText(Panel1, ID_STATICTEXT2, _("Tracknumber \n"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
StaticNumberText->Disable();
wxFont StaticNumberTextFont(10,wxSWISS,wxFONTSTYLE_NORMAL,wxNORMAL,false,_T("Arial"),wxFONTENCODING_DEFAULT);
StaticNumberText->SetFont(StaticNumberTextFont);
BoxSizer3->Add(StaticNumberText, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
ChoiceTrack = new wxChoice(Panel1, ID_CHOICE1, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_CHOICE1"));
ChoiceTrack->Disable();
BoxSizer4->Add(ChoiceTrack, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
ButtonOk = new wxButton(Panel1, ID_BUTTON1, _("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
BoxSizer5->Add(ButtonOk, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer5, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
Panel1->SetSizer(pPanelSizer);
pPanelSizer->Fit(Panel1);
pPanelSizer->SetSizeHints(Panel1);
Center();
Connect(ID_FILEPICKERCTRL1,wxEVT_COMMAND_FILEPICKER_CHANGED,(wxObjectEventFunction)&TrackDialog::OnXmlFilePickerCtrlFileChanged);
Connect(ID_CHOICE1,wxEVT_COMMAND_CHOICE_SELECTED,(wxObjectEventFunction)&TrackDialog::OnChoiceTrackSelect1);
Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&TrackDialog::OnButtonOkClick);
//*)
SetSize(DoGetBestClientSize());
Fit();
}
The text is changed from "Track number" to one of the options below:
void TrackDialog::setOutputAndChoice()
{
std::vector<wxString> storedTracks = m_xmlReader.getNamesOfTracks(m_path);
int numberOfTracks = storedTracks.size();
StaticNumberText->Enable();
wxString text;
// Make sure there are tracks stored in the file.
if(numberOfTracks > 0){
text = "There are ";
text += wxString::Format(wxT("%i"), numberOfTracks);
text += " tracks stored in the selected file. Select one."
"\nTrack 1 is the inner track.";
}
else{
text = "Opening file failed. Please chose another"
"file of the right format.";
}
StaticNumberText->SetLabel(text);
}
And this is what it looks like on desktop PC (on the tablet it looks the same, thanks to SetSize(DoGetBestClientSize());)
What can I do so that all of the text is displayed? I already tried to set it in the constructor before I call SetSizerAndFit() but then my program crashes if I want to close it...
Thank you for your help.
Edit: I put a panel in the sizer for the StaticNumberText and the text in it and I am able to display all of the text now, though now there is some nasty space underneath the StaticText:
There has to be a better way to properly layout dialogs with changing text...
Sizers need an action to get into game. User changing the size of the main (or dialog) window is definitely an action.
You can also trigger the action asking the dialog window to fit into its children. Call Fit() at the end of your TrackDialog::setOutputAndChoice()
Maybe the sizer for the StaticText there be inside the sizer for both TextCtrl and Button. Then the sizer for the StaticText will take the width of the TextCtrl.
Better, put the sizer for the StaticText, below and independently of the previous sizer.
The proportion of the StaticText, and the Panel in where is inside, must be set at 0.

How to size wxWindows properly

I have a wxWidgets C++ program made in Code::blocks. On the desktop PC it looks fine, but not on windows tablets.
The following picture is what it should look like (at least all of the text should be visible):
I already tried several ways, at the moment my code looks like this:
TrackDialog::TrackDialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,
const wxSize& size)
{
wxBoxSizer* BoxSizer4;
wxBoxSizer* BoxSizer5;
wxBoxSizer* BoxSizer2;
wxBoxSizer* BoxSizer1;
wxBoxSizer* BoxSizer3;
wxBoxSizer* pPanelSizer;
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP|wxSUNKEN_BORDER, _T("wxID_ANY"));
SetMinSize(wxSize(500,400));
Panel1 = new wxPanel(this, ID_PANEL1, wxPoint(184,136), wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
pPanelSizer = new wxBoxSizer(wxVERTICAL);
BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
StaticSelectText = new wxStaticText(Panel1, ID_STATICTEXT1, _("Select a *.xml file."), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
BoxSizer1->Add(StaticSelectText, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
XmlFilePickerCtrl = new wxFilePickerCtrl(Panel1, ID_FILEPICKERCTRL1, _T("./resources/"), wxEmptyString, _T("*.xml"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL, wxDefaultValidator, _T("ID_FILEPICKERCTRL1"));
BoxSizer2->Add(XmlFilePickerCtrl, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
StaticNumberText = new wxStaticText(Panel1, ID_STATICTEXT2, _("Tracknumber"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
StaticNumberText->Disable();
BoxSizer3->Add(StaticNumberText, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
ChoiceTrack = new wxChoice(Panel1, ID_CHOICE1, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_CHOICE1"));
ChoiceTrack->Disable();
BoxSizer4->Add(ChoiceTrack, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
ButtonOk = new wxButton(Panel1, ID_BUTTON1, _("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
BoxSizer5->Add(ButtonOk, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
pPanelSizer->Add(BoxSizer5, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
Panel1->SetSizer(pPanelSizer);
pPanelSizer->Fit(Panel1);
pPanelSizer->SetSizeHints(Panel1);
Center();
Connect(ID_FILEPICKERCTRL1,wxEVT_COMMAND_FILEPICKER_CHANGED,(wxObjectEventFunction)&TrackDialog::OnXmlFilePickerCtrlFileChanged);
Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&TrackDialog::OnButtonOkClick);
//*)
Connect(ID_CHOICE1,wxEVT_COMMAND_CHOICE_SELECTED,(wxObjectEventFunction)&TrackDialog::OnChoiceTrackSelect1);
SetSize(DoGetBestClientSize());
Fit();
}
Additionally, another dialog is way too big:
with this code:
PortsDialog::PortsDialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,
const wxSize& size)
{
//(*Initialize(PortsDialog)
wxBoxSizer* BoxSizer4;
wxBoxSizer* BoxSizer5;
wxBoxSizer* BoxSizer2;
wxBoxSizer* BoxSizer1;
wxBoxSizer* BoxSizer3;
Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id"));
SetClientSize(wxDefaultSize);
Move(wxDefaultPosition);
Panel1 = new wxPanel(this, ID_PANEL1, wxPoint(200,320), wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
BoxSizer1 = new wxBoxSizer(wxVERTICAL);
BoxSizer2 = new wxBoxSizer(wxVERTICAL);
StaticComText = new wxStaticText(Panel1, ID_STATICTEXT1, _("COM Ports"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
BoxSizer2->Add(StaticComText, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer1->Add(BoxSizer2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
TextCtrlVibroTacPort = new wxTextCtrl(Panel1, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
BoxSizer3->Add(TextCtrlVibroTacPort, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
ButtonVibroTacPort = new wxButton(Panel1, ID_BUTTON1, _("Set VibroTac Port"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
BoxSizer3->Add(ButtonVibroTacPort, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer1->Add(BoxSizer3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
TextCtrlGnssPort = new wxTextCtrl(Panel1, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL2"));
BoxSizer4->Add(TextCtrlGnssPort, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
ButtonGnssPort = new wxButton(Panel1, ID_BUTTON2, _("Set GNSS Port"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2"));
BoxSizer4->Add(ButtonGnssPort, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer1->Add(BoxSizer4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
ButtonClose = new wxButton(Panel1, ID_BUTTON3, _("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3"));
BoxSizer5->Add(ButtonClose, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
BoxSizer1->Add(BoxSizer5, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
Panel1->SetSizer(BoxSizer1);
BoxSizer1->Fit(Panel1);
BoxSizer1->SetSizeHints(Panel1);
Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&PortsDialog::OnButtonVibroTacPortClick);
Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&PortsDialog::OnButtonVibroTacPortClick);
Connect(ID_TEXTCTRL2,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&PortsDialog::OnButtonGnssPortClick);
Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&PortsDialog::OnButtonGnssPortClick);
Connect(ID_BUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&PortsDialog::OnButtonCloseClick);
//*)
SetSize(DoGetBestClientSize());
Fit();
}
I've seen many different methods to set the size, but until now I could not figure out a way that sets the size so that everything looks fine.
Thank you for your help.
Edit:
SetSizerAndFit(BoxSizer1); with the PortsDialog as Tibo suggested leads to the dialog being empty:
With SetSizerAndFit(pPanelSizer); in TrackDialog, it looks fine on start, but if I reload the text half of it is out of the window again and the program crashes if the window is closed... This is so confusing.
Concerning the version: I have Windows 10 Pro 64-bit version on all of my devices (tablet and PC) and I use wxWidgets v3.0.2 and Code::Blocks v13.12 (with GCC compiler following C++11 ISO)
It's really not clear what this question is about, there seem to be several completely unrelated things here and I'd advise closing/deleting this one and asking each of them in separate new submissions.
But to try to answer the first question, the text is not fully visible because there is not enough space for it on the tablet. It won't wrap on its own, you need to use a control with support for wrapping or call Wrap() yourself on wxStaticText manually.

wxWidgets C++ panel is invisible

I am starting to practise my skills with wxWidgets and I wanted to add some panel with two different texts above this slider, but when I tried, the result is invisible:
MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition) {
wxMenuBar *menubar;
wxMenu *file;
menubar = new wxMenuBar;
file = new wxMenu;
file->Append(wxID_OPEN, wxT("&Open"));
menubar->Append(file, wxT("&File"));
SetMenuBar(menubar);
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
this->SetSizer(vbox);
player_widget = new wxWindow(this, wxID_ANY);
player_widget->SetBackgroundColour(wxColour(wxT("black")));
vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
wxBoxSizer* bs = new wxBoxSizer(wxHORIZONTAL);
wxPanel* p1 = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxSize(0,20));
p1->SetSizer(bs);
p1->Enable(true);
p1->Show(true);
vbox->Add(p1,0,wxEXPAND);
wxStaticText* text1 = new wxStaticText(this,11, "text 1");
wxStaticText* text2 = new wxStaticText(this,12, "text 2");
bs->Add(text1);
bs->Add(text2);
timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
vbox->Add(timeline, 0, wxEXPAND);
wxPanel *controlPanel = new wxPanel(this, wxID_ANY);
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
controlPanel->SetSizer(hbox);
vbox->Add(controlPanel, 0, wxEXPAND);
playpause_button = new wxButton(controlPanel, myID_PLAYPAUSE, wxT("Play"));
stop_button = new wxButton(controlPanel, myID_STOP, wxT("Stop"));
volume_slider = new wxSlider(controlPanel, myID_VOLUME, VOLUME_MAX, 0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
hbox->Add(playpause_button);
hbox->Add(stop_button);
hbox->AddStretchSpacer();
hbox->Add(volume_slider);
}
Any ideas what I did wrong?
Change parent of text1 and text2 to p1.
It is simpler to use just one panel that holds everything.
Something like this ( a complete program )
#include <wx/wx.h>
#include <wx/app.h>
class cApp : public wxApp
{
public:
virtual bool OnInit();
};
#define TIMELINE_MAX 100
#define VOLUME_MAX 100
enum {
myID_TIMELINE,
myID_PLAYPAUSE,
myID_STOP,
myID_VOLUME
};
class cFrame: public wxFrame
{
wxWindow * player_widget;
wxSlider * timeline;
wxSlider * volume_slider;
wxButton * playpause_button;
wxButton * stop_button;
public:
cFrame(wxFrame *frame, const wxString& title)
: wxFrame(frame, -1, title, wxPoint(-1,-1),wxSize(600,600))
{
wxMenuBar *menubar;
wxMenu *file;
menubar = new wxMenuBar;
file = new wxMenu;
file->Append(wxID_OPEN, wxT("&Open"));
menubar->Append(file, wxT("&File"));
SetMenuBar(menubar);
// define one panel to hold everything
// make it big enough to fill the frame
wxPanel* p1 = new wxPanel(this,wxID_ANY, wxPoint(-1,-1),wxSize(600,600) );
// top level sizer to hold everything
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
// add window widget at top
player_widget = new wxWindow(p1, wxID_ANY);
player_widget->SetBackgroundColour(wxColour(wxT("black")));
vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
// add some texts in a horizontal row
wxBoxSizer* bs = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* text1 = new wxStaticText(p1,11, "text 1");
wxStaticText* text2 = new wxStaticText(p1,12, "text 2");
bs->Add(text1);
bs->Add(text2);
// add texts just below window widget
vbox->Add( bs );
// add slider below texts
timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
vbox->Add(timeline, 0, wxEXPAND);
// some more controls in a row
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
playpause_button = new wxButton(p1, myID_PLAYPAUSE, wxT("Play"));
stop_button = new wxButton(p1, myID_STOP, wxT("Stop"));
volume_slider = new wxSlider(p1, myID_VOLUME, VOLUME_MAX,
0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
hbox->Add(playpause_button);
hbox->Add(stop_button);
hbox->AddStretchSpacer();
hbox->Add(volume_slider);
// add controls below big slider
vbox->Add( hbox );
// make everything happen
SetSizer(vbox);
}
};
IMPLEMENT_APP(cApp);
bool cApp::OnInit()
{
cFrame* frame = new cFrame(0L, _("wx Starter"));
frame->Show();
return true;
}
This gives:
Here's the thing about computer programming: at some time you always have to settle down and write some code. All those applications, like wxFormBuilder, that promise to write code for you have to be abandoned at some point and you actually have to do some work ( Here is a link to more about this )

Spacer added to inner wxBoxSizer doesn't work in wxWidgets

I have an issue with spacer inside of the inner wxBoxSizer.
Here is the sample code.
class Frame : public wxFrame
{
public:
Frame()
: wxFrame(nullptr,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxSize(600, 200))
{
wxPanel* panel = new wxPanel(this);
// Some OUTER SIZER
wxBoxSizer* mainS = new wxBoxSizer(wxVERTICAL);
// INNER HORIZONTAL SIZER
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* text = new wxStaticText(panel, wxID_ANY, wxT("Some Text"));
sizer->Add(text, 0, wxALL, 5);
wxComboBox* comboBox = new wxComboBox(panel, wxID_ANY, wxT("Combo"));
sizer->Add(comboBox, 0, wxALL, 5);
// SPACER
sizer->Add(0, 0, 1, wxEXPAND, 5);
wxButton* button = new wxButton(panel, wxID_ANY, wxT("Some button"));
sizer->Add(button, 0, wxALL, 5);
mainS->Add(sizer, 0, wxALL, 5);
panel->SetSizer(mainS);
// PANEL SIZER
wxBoxSizer* panelSizer = new wxBoxSizer(wxHORIZONTAL);
panelSizer->Add(panel, 1, wxEXPAND, 5);
SetSizer(panelSizer);
Layout();
Centre(wxBOTH);
}
};
class WxguiApp
: public wxApp
{
public:
bool OnInit() override
{
Frame* w = new Frame();
w->Show();
SetTopWindow(w);
return true;
}
};
IMPLEMENT_APP(WxguiApp);
If I remove outer sizer spacer starts working fine. Is it bug in my code? Or maybe some issue with wxWidgets?
I couldn't find answer, maybe someone help? wxWidgets 3.0.2
Your inner sizer (sizer) won't expand in the horizontal direction because you didn't tell its parent sizer (mainS) to do it when adding it, so your spacer will always be 0 pixels wide, which is its initial and minimal width.
To fix this, you just need to change the mainS->Add(sizer, 0, wxALL, 5) line to use wxALL | wxEXPAND.
Additionally, I strongly encourage you to look at using wxSizerFlags instead of the cryptic syntax shown above. And, last and really least, but still worth mentioning, prefer using much more readable AddStretchSpacer() to the confusing Add(0, 0, 1, wxEXPAND, 5) call (it's confusing because expanding your spacer doesn't do anything and border size is not taken into account without any border flags).

Custom Dialog Event Handling with Event Tables

I pretend to "grab" and process the events: EVT_TEXT from wxTextCtrl and EVT_BUTTON from wxID_APPLY.
I try handling the events with Event Tables and I can't? Why?
The source code:
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
class Dialog : public wxDialog
{
public:
Dialog(wxWindow *parent, const wxString &title);
private:
void OnNameChange(wxCommandEvent &event);
void OnApply(wxCommandEvent &event);
wxDECLARE_EVENT_TABLE();
wxTextCtrl *m_name;
};
enum
{
ID_NAME = 1
};
Dialog::Dialog(wxWindow *parent, const wxString &title) :
wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
SetSizer(vbox);
wxFlexGridSizer *flexGrid = new wxFlexGridSizer(2, 2, 5, 5);
wxStaticText *label = new wxStaticText(this, wxID_ANY, "&Name:");
flexGrid->Add(label);
m_name = new wxTextCtrl(this, ID_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
flexGrid->Add(m_name, 1, wxEXPAND);
label = new wxStaticText(this, wxID_ANY, "&Description:");
flexGrid->Add(label);
m_description = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
flexGrid->Add(m_description, 1, wxEXPAND);
flexGrid->AddGrowableRow(1, 1);
flexGrid->AddGrowableCol(1, 1);
vbox->Add(flexGrid, 1, wxALL | wxEXPAND, 15);
vbox->Add(CreateSeparatedButtonSizer(wxAPPLY | wxCANCEL), 0, wxEXPAND | wxALL, 5);
}
void Dialog::OnNameChange(wxCommandEvent &event)
{
m_description->AppendText("Hello\n");
}
void Dialog::OnApply(wxCommandEvent &event)
{
m_description->AppendText("Apply\n");
}
wxBEGIN_EVENT_TABLE(Dialog, wxDialog)
EVT_TEXT(ID_NAME, Dialog::OnNameChange)
EVT_BUTTON(wxID_APPLY, Dialog::OnApply)
wxEND_EVENT_TABLE()
It's only possible to handle the events dynamically?
Bind(wxEVT_TEXT, &Dialog::OnNameChange, this, m_name->GetId());
The code as shown absolutely should work. It's not self-contained, so I can't test it, but there must be something else not shown here preventing it from working. Please try to make a SSCCE if you still can't isolate the problem yourself.