An image panel
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Here's how to draw an image, make an image component or paint on the background of a panel.
(If all you want is place an icon somewhere, create a simple wxStaticBitmap and add it to a sizer, i.e. no need for a wxPanel. On most platforms, wxStaticBitmap will also work fine, except on Windows because it doesn't accept big images, so ideally use wxStaticBitmap only for icons)
A simple image panel
#include <wx/wx.h>
#include <wx/sizer.h>
class wxImagePanel : public wxPanel
{
wxBitmap image;
public:
wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format);
void paintEvent(wxPaintEvent & evt);
void paintNow();
void render(wxDC& dc);
// some useful events
/*
void mouseMoved(wxMouseEvent& event);
void mouseDown(wxMouseEvent& event);
void mouseWheelMoved(wxMouseEvent& event);
void mouseReleased(wxMouseEvent& event);
void rightClick(wxMouseEvent& event);
void mouseLeftWindow(wxMouseEvent& event);
void keyPressed(wxKeyEvent& event);
void keyReleased(wxKeyEvent& event);
*/
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxImagePanel, wxPanel)
// some useful events
/*
EVT_MOTION(wxImagePanel::mouseMoved)
EVT_LEFT_DOWN(wxImagePanel::mouseDown)
EVT_LEFT_UP(wxImagePanel::mouseReleased)
EVT_RIGHT_DOWN(wxImagePanel::rightClick)
EVT_LEAVE_WINDOW(wxImagePanel::mouseLeftWindow)
EVT_KEY_DOWN(wxImagePanel::keyPressed)
EVT_KEY_UP(wxImagePanel::keyReleased)
EVT_MOUSEWHEEL(wxImagePanel::mouseWheelMoved)
*/
// catch paint events
EVT_PAINT(wxImagePanel::paintEvent)
END_EVENT_TABLE()
// some useful events
/*
void wxImagePanel::mouseMoved(wxMouseEvent& event) {}
void wxImagePanel::mouseDown(wxMouseEvent& event) {}
void wxImagePanel::mouseWheelMoved(wxMouseEvent& event) {}
void wxImagePanel::mouseReleased(wxMouseEvent& event) {}
void wxImagePanel::rightClick(wxMouseEvent& event) {}
void wxImagePanel::mouseLeftWindow(wxMouseEvent& event) {}
void wxImagePanel::keyPressed(wxKeyEvent& event) {}
void wxImagePanel::keyReleased(wxKeyEvent& event) {}
*/
wxImagePanel::wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format) :
wxPanel(parent)
{
// load the file... ideally add a check to see if loading was successful
image.LoadFile(file, format);
}
/*
* Called by the system of by wxWidgets when the panel needs
* to be redrawn. You can also trigger this call by
* calling Refresh()/Update().
*/
void wxImagePanel::paintEvent(wxPaintEvent & evt)
{
// depending on your system you may need to look at double-buffered dcs
wxPaintDC dc(this);
render(dc);
}
/*
* Alternatively, you can use a clientDC to paint on the panel
* at any time. Using this generally does not free you from
* catching paint events, since it is possible that e.g. the window
* manager throws away your drawing when the window comes to the
* background, and expects you will redraw it when the window comes
* back (by sending a paint event).
*/
void wxImagePanel::paintNow()
{
// depending on your system you may need to look at double-buffered dcs
wxClientDC dc(this);
render(dc);
}
/*
* Here we do the actual rendering. I put it in a separate
* method so that it can work no matter what type of DC
* (e.g. wxPaintDC or wxClientDC) is used.
*/
void wxImagePanel::render(wxDC& dc)
{
dc.DrawBitmap( image, 0, 0, false );
}
// ----------------------------------------
// how-to-use example
class MyApp: public wxApp
{
wxFrame *frame;
wxImagePanel * drawPane;
public:
bool OnInit()
{
// make sure to call this first
wxInitAllImageHandlers();
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
frame = new wxFrame(NULL, wxID_ANY, wxT("Hello wxDC"), wxPoint(50,50), wxSize(800,600));
// then simply create like this
drawPane = new wxImagePanel( frame, wxT("image.jpg"), wxBITMAP_TYPE_JPEG);
sizer->Add(drawPane, 1, wxEXPAND);
frame->SetSizer(sizer);
frame->Show();
return true;
}
};
IMPLEMENT_APP(MyApp)
A panel in which the image resizes
#include <wx/wx.h>
#include <wx/sizer.h>
class wxImagePanel : public wxPanel
{
wxImage image;
wxBitmap resized;
int w, h;
public:
wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format);
void paintEvent(wxPaintEvent & evt);
void paintNow();
void OnSize(wxSizeEvent& event);
void render(wxDC& dc);
// some useful events
/*
void mouseMoved(wxMouseEvent& event);
void mouseDown(wxMouseEvent& event);
void mouseWheelMoved(wxMouseEvent& event);
void mouseReleased(wxMouseEvent& event);
void rightClick(wxMouseEvent& event);
void mouseLeftWindow(wxMouseEvent& event);
void keyPressed(wxKeyEvent& event);
void keyReleased(wxKeyEvent& event);
*/
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxImagePanel, wxPanel)
// some useful events
/*
EVT_MOTION(wxImagePanel::mouseMoved)
EVT_LEFT_DOWN(wxImagePanel::mouseDown)
EVT_LEFT_UP(wxImagePanel::mouseReleased)
EVT_RIGHT_DOWN(wxImagePanel::rightClick)
EVT_LEAVE_WINDOW(wxImagePanel::mouseLeftWindow)
EVT_KEY_DOWN(wxImagePanel::keyPressed)
EVT_KEY_UP(wxImagePanel::keyReleased)
EVT_MOUSEWHEEL(wxImagePanel::mouseWheelMoved)
*/
// catch paint events
EVT_PAINT(wxImagePanel::paintEvent)
//Size event
EVT_SIZE(wxImagePanel::OnSize)
END_EVENT_TABLE()
// some useful events
/*
void wxImagePanel::mouseMoved(wxMouseEvent& event) {}
void wxImagePanel::mouseDown(wxMouseEvent& event) {}
void wxImagePanel::mouseWheelMoved(wxMouseEvent& event) {}
void wxImagePanel::mouseReleased(wxMouseEvent& event) {}
void wxImagePanel::rightClick(wxMouseEvent& event) {}
void wxImagePanel::mouseLeftWindow(wxMouseEvent& event) {}
void wxImagePanel::keyPressed(wxKeyEvent& event) {}
void wxImagePanel::keyReleased(wxKeyEvent& event) {}
*/
wxImagePanel::wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format) :
wxPanel(parent)
{
// load the file... ideally add a check to see if loading was successful
image.LoadFile(file, format);
w = -1;
h = -1;
}
/*
* Called by the system of by wxWidgets when the panel needs
* to be redrawn. You can also trigger this call by
* calling Refresh()/Update().
*/
void wxImagePanel::paintEvent(wxPaintEvent & evt)
{
// depending on your system you may need to look at double-buffered dcs
wxPaintDC dc(this);
render(dc);
}
/*
* Alternatively, you can use a clientDC to paint on the panel
* at any time. Using this generally does not free you from
* catching paint events, since it is possible that e.g. the window
* manager throws away your drawing when the window comes to the
* background, and expects you will redraw it when the window comes
* back (by sending a paint event).
*/
void wxImagePanel::paintNow()
{
// depending on your system you may need to look at double-buffered dcs
wxClientDC dc(this);
render(dc);
}
/*
* Here we do the actual rendering. I put it in a separate
* method so that it can work no matter what type of DC
* (e.g. wxPaintDC or wxClientDC) is used.
*/
void wxImagePanel::render(wxDC& dc)
{
int neww, newh;
dc.GetSize( &neww, &newh );
if( neww != w || newh != h )
{
resized = wxBitmap( image.Scale( neww, newh /*, wxIMAGE_QUALITY_HIGH*/ ) );
w = neww;
h = newh;
dc.DrawBitmap( resized, 0, 0, false );
}else{
dc.DrawBitmap( resized, 0, 0, false );
}
}
/*
* Here we call refresh to tell the panel to draw itself again.
* So when the user resizes the image panel the image should be resized too.
*/
void wxImagePanel::OnSize(wxSizeEvent& event){
Refresh();
//skip the event.
event.Skip();
}
// ----------------------------------------
// how-to-use example
class MyApp: public wxApp
{
wxFrame *frame;
wxImagePanel * drawPane;
public:
bool OnInit()
{
// make sure to call this first
wxInitAllImageHandlers();
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
frame = new wxFrame(NULL, wxID_ANY, wxT("Hello wxDC"), wxPoint(50,50), wxSize(800,600));
// then simply create like this
drawPane = new wxImagePanel( frame, wxT("image.jpg"), wxBITMAP_TYPE_JPEG);
sizer->Add(drawPane, 1, wxEXPAND);
frame->SetSizer(sizer);
frame->Show();
return true;
}
};
IMPLEMENT_APP(MyApp)