I am trying to set an image as the background but I have no idea how to do it.
It has been hours. The first lines of code I copied from somebody and they seemed alright but it still doesn't work.
The error that I have appears in a separate window and says it cannot load/find the image.
#include "MainFrame.h"
#include <wx/wx.h>
#include "FrameTwo.h"
#include "wx/custombgwin.h"
#include <wx/dcclient.h>
enum IDs {
BUTTON_ID=2
};
wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_BUTTON(BUTTON_ID, MainFrame::OnLoginClicked)
wxEND_EVENT_TABLE()
MainFrame::MainFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, title) {
wxPanel* panel = new wxPanel(this);
wxClientDC dc(panel);
wxMemoryDC mdc;
int w, h;
w = 600;
h = 600;
dc.GetSize(&w, &h);
wxImage img(wxT("C:\\Users\\ALEX\\Desktop\\background_uno.jpeg"), wxBITMAP_TYPE_JPEG);
wxBitmap cat(img.Scale(w, h, wxIMAGE_QUALITY_HIGH));
mdc.SelectObject(cat);
dc.Blit(0, 0, cat.GetWidth(), cat.GetHeight(), &mdc, 0, 0, wxCOPY, 0);
mdc.SelectObject(wxNullBitmap);
//panel->SetBackgroundColour(wxColour(255, 102, 102)); //light orange-red
//panel->SetBackgroundColour(wxColour(155, 202, 62)); //fresh green
wxButton* login = new wxButton(panel, BUTTON_ID, "Log in", wxPoint(340, 350), wxSize(100, 35));
CreateStatusBar(); //creates a bar in the bottom of the frame
//wxBoxSizer* sizer = new wxBoxSizer(wxALIGN_CENTER_VERTICAL);
//sizer -> Add(login, 1, wxEXPAND | wxALL, 10);
wxButton* exit = new wxButton(panel, wxID_OK, "Exit", wxPoint(340, 390), wxSize(100, 35));
exit->Bind(wxEVT_BUTTON, &MainFrame::OnExitClicked, this);
panel->SetFont(panel->GetFont().Scale(2.5));
wxStaticText* staticText = new wxStaticText(panel, wxID_ANY, "UNO DELUXE", wxPoint(300, 40));
panel->SetFont(panel->GetFont().Scale(0.5));
wxStaticText* username = new wxStaticText(panel, wxID_ANY, "Enter username: ", wxPoint(180, 250));
wxTextCtrl* textCtrl = new wxTextCtrl(panel, wxID_ANY, " ", wxPoint(300, 250), wxSize(250, -1));
wxStaticText* password = new wxStaticText(panel, wxID_ANY, "Enter password: ", wxPoint(180, 290));
wxTextCtrl* textCtrl2 = new wxTextCtrl(panel, wxID_ANY, "", wxPoint(300, 290), wxSize(250, -1), wxTE_PASSWORD);
}
I can't help you with the program not being able to find the image - the image needs to exist either in the application's working folder or on an absolute path.
You can get around this by including the image in the executable. Unfortunately there is no consistent cross-platform way to do this - windows and mac have separate ways of doing this but GTK has no way at all. Here are some suggestions from the wiki for some possible workarounds.
Regardless of the method used to get the image into the application, you should not draw it with a client DC. Instead you should handle the paint event for the panel and draw the image in the handler for that event. Here's an example:
#include <wx/wx.h>
class ImageBgFrame: public wxFrame
{
public:
ImageBgFrame(wxFrame *frame, const wxString& title);
private:
void OnImagePanelPaint(wxPaintEvent&);
void OnExit(wxCommandEvent&);
void CreateScaledBg();
wxPanel* m_imagePanel;
wxImage m_image;
wxBitmap m_scaledBg;
};
ImageBgFrame::ImageBgFrame(wxFrame *frame, const wxString& title)
:wxFrame(frame, wxID_ANY, title)
{
::wxInitAllImageHandlers();
// Try to load the image.
m_image = wxImage("Thinking-of-getting-a-cat.png", wxBITMAP_TYPE_PNG);
if ( !m_image.IsOk() )
{
return;
}
// Create the controls.
m_imagePanel = new wxPanel(this, wxID_ANY);
CreateScaledBg();
wxButton* exit = new wxButton(m_imagePanel, wxID_OK, "Exit");
// Arrang the controls with a sizer.
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(exit,wxSizerFlags().Border(wxALL));
m_imagePanel->SetSizer(szr);
Layout();
// Bind Event Handlers
m_imagePanel->Bind(wxEVT_PAINT, &ImageBgFrame::OnImagePanelPaint, this);
exit->Bind(wxEVT_BUTTON, &ImageBgFrame::OnExit, this);
}
void ImageBgFrame::OnImagePanelPaint(wxPaintEvent&)
{
if ( m_imagePanel->GetSize() != m_scaledBg.GetSize() )
{
CreateScaledBg();
}
wxPaintDC dc(m_imagePanel);
dc.DrawBitmap(m_scaledBg,0,0);
}
void ImageBgFrame::OnExit(wxCommandEvent&)
{
Close();
}
void ImageBgFrame::CreateScaledBg()
{
wxSize sz = m_imagePanel->GetSize();
m_scaledBg = wxBitmap(m_image.Scale(sz.GetWidth(), sz.GetHeight(),
wxIMAGE_QUALITY_NORMAL));
}
class ImageBgApp : public wxApp
{
public:
bool OnInit()
{
ImageBgFrame* frame = new ImageBgFrame(NULL, "Image BG");
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(ImageBgApp);
This assumes that the image "Thinking-of-getting-a-cat.png" is in the application's working folder. On GTK it looks like this:
I've also made a few other changes to the code you gave:
I'm using Bind to connect the event handlers instead of static event tables.
I'm using default sizes for the controls instead of setting the size explicitly and laying out the controls in a sizer instead of setting explicit location.
Both of these changes are a more modern way of doing things.
Related
In my mainwindow, I am setting the background Image and added few buttons using the wxBoxSizer in CreateWidgets. Now on clicking one of the buttons, it should replace the background Image and hide the old wxBoxSizer and create a new one.
After setting the new image it is always calling child OnPaint function not the parent OnPaint function.
MainFrame::MainFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
// set the frame icon
SetIcon(wxICON(sample));
wxString fileName = wxT("./images/image1.png");
LoadBitmap(fileName);
SetSize(size);
CreateWidgets();
}
void MainFrame::LoadBitmaps(wxString filename) {
if (!wxFile::Exists(filename))
wxLogWarning("Can't find image files");
wxImage::AddHandler(new wxPNGHandler);
image.LoadFile(filename);
size.SetHeight(image.GetHeight() + 60);
size.SetWidth(image.GetWidth() + 25);
}
void MainFrame::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
wxPaintDC dc(this);
wxBitmap bitmap(image);
dc.DrawBitmap(bitmap, 5, 5, false);
}
void MainFrame::CreateWidgets() {
wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
std::vector<wxString> fileNames;
fileNames.push_back(wxT("./images/img.png"));
std::vector<wxString> rollover_files;
rollover_files.push_back(wxT("./images/rollover_img.png"));
std::vector<wxImage> images;
wxImage image1(fileNames[0]);
wxImage rollover_image1(rollover_files[0]);
wxBitmap bitmap1(image1);
wxBitmap rollover_bitmap1(rollover_image1);
const long id = 6000;
MWCustomBitmap *bitmapCtrl1 = new MWCustomBitmap(this, bitmap1, TetraMeshingBitMapBtn, rollover_bitmap1, NULL, wxDefaultPosition, wxDefaultSize);
button_sizer->Add(bitmapCtrl1, 0, wxALL, 10);
main_sizer->AddSpacer(350);
main_sizer->Add(button_sizer, wxSizerFlags().Center());
this->SetSizer(main_sizer);
}
Here on clicking button Loadfile(filename) is not working.
void MWCustomBitmap::OnBtnClicked(wxCommandEvent &evt) {
wxString filename = wxT("./images/img3.png");
if (!wxFile::Exists(filename))
wxLogWarning("Can't find image files");
wxImage::AddHandler(new wxPNGHandler);
((MainFrame*)(m_pParentwindow))->GetImage().LoadFile(filename);
}
PS: I am learning wxWidgets.
how to show another frame after button click event?
like this
My code here show window OnInit. but what to do next?
I did not find how to do this. little experience with this.
I comment the window that should be.
enum
{
wxID_First_Load = 5000,
wxID_First_Frame,
wxID_First_Panel
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void fileLoad(wxCommandEvent& event);
private:
int file_count = 0;
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(wxID_First_Load, MyFrame::fileLoad)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame("Hello World", wxDefaultPosition, wxSize(450, 250));
frame->SetWindowStyle(wxCAPTION | wxSYSTEM_MENU );
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_First_Frame, title, pos, size)
{
wxBoxSizer *first_sizer = new wxBoxSizer(wxVERTICAL);
wxPanel *firstPanel = new wxPanel(this, wxID_First_Panel);
wxButton *firstButton_Load = new wxButton(firstPanel, wxID_First_Load, "Choose file");
firstPanel->SetSizer(first_sizer);
first_sizer->Add(firstButton_Load, 1, wxEXPAND | wxALL, 10);
firstPanel->SetSizer(first_sizer);
}
void MyFrame::fileLoad(wxCommandEvent& WXUNUSED(event))
{
file_count = 2;
}
Second Frame or window:
wxPanel *firstPanel = new wxPanel(this, wxID_First_Panel);
wxBoxSizer *second_sizer = new wxBoxSizer(wxVERTICAL);
for (int i = 0; i < file_count; i++)
{
second_sizer->Add(new wxTextCtrl(firstPanel, wxWindowID(i), "Hello", wxDefaultPosition, wxSize(235, 60)), wxSizerFlags(0).Border(wxALL, 5));
}
firstPanel->SetSizer(second_sizer);
To create a new frame you need to create a new object of wxFrame class or a class deriving from it. Typically, you want to put some data and logic into your new frame, so you would create some class, e.g. MySecondaryFrame (but hopefully with a better name) , inheriting from wxFrame in a similar way to your existing MyFrame class.
Then to show it you would do the same thing that you do in MyApp::OnInit(), i.e. create a new object of this class and call Show() to actually show it.
P.S. Note that your SetWindowStyle(wxCAPTION | wxSYSTEM_MENU ) call is unnecessary, these styles are already on by default. Also, hard coding the frame size in pixels is a bad idea, consider using sizers to determine the best size suitable for the frame contents or just leave it unspecified if it really doesn't matter.
I want to view an image in one of wxSplitterWindow using wxScrolledWindow.
I derived class from wxPanel, which I add into wxScrolledWindow. But the result is not what i want.(
class ImagePanel : public wxPanel
{
public:
//ImagePanel(wxFrame* parent);
ImagePanel(wxWindow* parent);
void paintEvent(wxPaintEvent& event);
void paintNow();
void setBitmap(wxBitmap& imBitmap);
void setBitmap(wxImage& img);
int GetHeight();
int GetWidth();
void render(wxDC& dc);
DECLARE_EVENT_TABLE()
private:
wxBitmap curBitmap;
};
Paint event:
void ImagePanel::paintEvent(wxPaintEvent& event)
{
wxBufferedPaintDC dc(this);
render(dc);
}
This is how I have written the interface into main frame constructor:
topSizer = new wxBoxSizer(wxVERTICAL);
topSplitter = new wxSplitterWindow(this,ID_TOPSPLITTER,wxDefaultPosition,wxDefaultSize,wxSP_LIVE_UPDATE|wxSP_3D);
topSizer->Add(topSplitter,1,wxALL|wxEXPAND,0);
imagePanel = new wxPanel(topSplitter,ID_IMAGEPANEL);
imageSizer = new wxBoxSizer(wxVERTICAL);
imagePanel->SetSizer(imageSizer);
optionPanel = new wxPanel(topSplitter,ID_OPTIONPANEL);
optionSizer = new wxBoxSizer(wxVERTICAL);
optionPanel->SetSizer(optionSizer);
topSplitter->SplitVertically(imagePanel, optionPanel);
topSplitter->SetMinimumPaneSize(200);
//===========================================
//image panel interface
imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
imgArea = new ImagePanel(imageScWindow);
imageSizer->Add(imageScWindow,1,wxEXPAND,0);
scrollSizer = new wxBoxSizer(wxVERTICAL);
imageScWindow->SetSizer(scrollSizer);
scrollSizer->Add(imgArea,1,wxEXPAND,0);
imageScWindow->SetTargetWindow(imgArea);
And this is the function that loads image:
void MainFrame::Setpic(wxCommandEvent& event)
{
wxString path = GetCurrentWorkingDir()+wxT("\\")+tmptxt1->GetValue();
wxImage img(path);
wxBitmap imBitmap(img,-1);
imgArea->setBitmap(imBitmap);
imageScWindow->SetScrollbars(1,1,imgArea->GetWidth(),imgArea->GetHeight());
imageScWindow->Refresh();
}
Thats what i get:
https://i.imgur.com/x1GIlrl.png
I have also tried to do like this in the constructor, without SetTargetArea:
//===========================================
//image panel interface
imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
imgArea = new ImagePanel(imageScWindow);
imageSizer->Add(imageScWindow,1,wxEXPAND,0);
scrollSizer = new wxBoxSizer(wxVERTICAL);
imageScWindow->SetSizer(scrollSizer);
scrollSizer->Add(imgArea,1,wxEXPAND,0);
Then image shows properly, but if I change the frame size or move splitter, scrollbars disappear, and I have to set them again somwhere.
Then i tried to do like this:
int prvx,prvy;
void ImagePanel::paintEvent(wxPaintEvent& event)
{
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->GetViewStart(&prvx,&prvy);
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->SetScrollbars(1,1,curBitmap.GetWidth(),curBitmap.GetHeight());
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->Scroll(wxPoint(prvx,prvy));
wxBufferedPaintDC dc(this);
render(dc);
}
It shows properly, but lags while scrolling, even without wxFULL_REPAINT_ON_RESIZE in wxScrolledWindow. The reason why it is in paint event: if I add this into OnSize event, program crashes. What to do?
I'm not sure where to begin answering your question. Here's a minimal sample of a frame that has a splitter with a bitmap on the left and a panel on the right. I hope you can adapt this sample to do what you need.
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/scrolwin.h>
#include <wx/splitter.h>
#include <wx/dcbuffer.h>
class MyFrame : public wxFrame
{
public:
MyFrame( wxWindow* parent, int id = wxID_ANY, wxString title = "Demo",
wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize,
int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
private:
void OnScrollPaint( wxPaintEvent& event );
wxScrolledCanvas* m_canvas;
wxBitmap m_bitmap;
};
MyFrame::MyFrame( wxWindow* parent, int id, wxString title, wxPoint pos,
wxSize size, int style )
:wxFrame( parent, id, title, pos, size, style )
{
m_bitmap=wxBitmap ("test.png", wxBITMAP_TYPE_PNG );
wxSplitterWindow* m_splitter1
= new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSP_LIVE_UPDATE );
m_canvas = new wxScrolledCanvas( m_splitter1, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSTATIC_BORDER|wxHSCROLL|wxVSCROLL );
m_canvas->SetScrollRate( 5, 5 );
m_canvas->SetVirtualSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
m_canvas->SetBackgroundStyle(wxBG_STYLE_PAINT);
m_canvas->Bind( wxEVT_PAINT, &MyFrame::OnScrollPaint , this );
wxPanel* m_panel2 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL );
m_splitter1->SplitVertically( m_canvas, m_panel2, GetSize().x/2 );
}
void MyFrame::OnScrollPaint( wxPaintEvent& event )
{
wxAutoBufferedPaintDC dc(m_canvas);
m_canvas->DoPrepareDC(dc);
dc.Clear();
dc.DrawBitmap(m_bitmap,0,0);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
wxInitAllImageHandlers();
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
To run this, be sure to change "test.png" in line 35 to the name of an actual image file on your computer (and change wxBITMAP_TYPE_PNG if the image file isn't a png).
The important parts are:
Set the background style of the canvas to wxBG_STYLE_PAINT as shown in line 46.
In the paint handler, call the DoPrepareDC method on the paintdc.
By the way, the paint handler shown in my sample isn't very good. It draws the entire bitmap every time. A better approach would be to get the update region and only redraw the parts that are needed, but I wanted to keep this simple.
I have 2 wxDialogs with the button which makes each of them top most dialog(wxSTAY_ON_TOP) after button click.
Workflow:
I make one of them top most, checked - dialog become top most.
I clicked once more and dialog become not top most, checked - ok.
Made both of them top most, checked - ok, both top most.
Made one of them not top most after step 3, checked - accordinly to logs 1 - top most, another is not top most, but if I click somewhere both behaves like not top most. I have tried with wxFrame, with more than 2 wxDialogs - result same. Maybe I missing something or threre is a bug. Please help.
wxWidgets 3.0.2, Windows
Simple frame which owns dialogs
class Frame : public wxFrame
{
public:
Frame()
: wxFrame(nullptr, wxID_ANY, wxEmptyString, wxPoint(1100, 300), wxSize(200, 200))
{
wxBoxSizer* sz = new wxBoxSizer(wxVERTICAL);
wxStaticText* text = new wxStaticText(this, wxID_ANY, "Parent Frame");
sz->Add(text, 0, wxALL, 5);
SetSizer(sz);
Layout();
}
};
Dialog class
class Dialog : public wxDialog
{
public:
Dialog(wxWindow* parent, wxPoint pos)
: wxDialog(parent, wxID_ANY, "", pos, wxSize(200, 200),
wxFRAME_NO_TASKBAR | wxTAB_TRAVERSAL | wxBORDER_NONE)
{
wxBoxSizer* mainS = new wxBoxSizer(wxVERTICAL);
wxButton* button = new wxButton(this, wxID_ANY, "Top Most");
mainS->Add(button, 0, wxALL, 5);
SetSizer(mainS);
Layout();
button->Bind(wxEVT_BUTTON, &Dialog::onButton, this);
}
void onButton(wxCommandEvent&)
{
bool isTopMost = (GetWindowStyle() & wxSTAY_ON_TOP) != 0;
if (isTopMost) {
// Makes not top most dynamically
SetWindowStyle(GetWindowStyle() & ~wxSTAY_ON_TOP);
}
else {
// Makes top most dynamically
SetWindowStyle(GetWindowStyle() | wxSTAY_ON_TOP);
}
}
};
Calling sample
class WxguiApp : public wxApp
{
public:
bool OnInit() override
{
Frame* mainWnd = new Frame();
mainWnd->Show();
SetTopWindow(mainWnd);
Dialog* dlg1 = new Dialog(mainWnd, wxPoint(500, 300));
dlg1->Show();
Dialog* dlg2 = new Dialog(mainWnd, wxPoint(800, 300));
dlg2->Show();
return true;
}
};
IMPLEMENT_APP(WxguiApp);
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 )