c++imagewxpythonwxwidgetswxtextctrl

wxWidgets: Frame size is not changing in Image panel


I am using wxWidgets 'An Image Panel' code. Here I made only one change. I want frame size should be equal to image size, My Image size is 762x463, but my frame size is different. frame SetSize function is not working.

wxImagePanel::wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format) :
wxPanel(parent)
{
    image.LoadFile(file, format);
}

void wxImagePanel::paintEvent(wxPaintEvent & evt)
{
    // depending on your system you may need to look at double-buffered dcs
    wxPaintDC dc(this);
    render(dc);
}

void wxImagePanel::paintNow()
{
    // depending on your system you may need to look at double-buffered dcs
    wxClientDC dc(this);
    render(dc);
}

void wxImagePanel::render(wxDC&  dc)
{
    dc.DrawBitmap( image, 0, 0, false );
}

class MyApp: public wxApp
    {
        
        wxFrame *frame;
        wxImagePanel * drawPane;
    public:
        bool OnInit()
        {
            // make sure to call this first
            wxInitAllImageHandlers();
            
            wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
            wxBitmap image(wxT("properties.png"), wxBITMAP_TYPE_PNG);
            frame = new wxFrame(NULL, wxID_ANY, wxT("Hello wxDC"), wxPoint(50,50), wxSize(image.GetWidth(), image.GetHeight()));  // 762x463
            
            // 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;
        } 
        
    };

Solution

  • To make the frame sized to display the image, you need to make 2 changes:

    1. In the constructor wxImagePanel::wxImagePanel, you need to add a line to set a minimum size for the image panel.
    wxImagePanel::wxImagePanel(wxFrame* parent, wxString file, wxBitmapType format) :
    wxPanel(parent)
    {
        image.LoadFile(file, format);
        SetMinSize(image.GetSize());
    ...
    

    An alternate, and possibly better, solution would be to override wxWindow::DoGetBestClientSize for your wxImagePanel class and have it return image.GetSize();.

    Incidentally, in the code shown above, there is nothing that actually connects the paint handler to the paint event, so you probably also want to add a line like

    Bind(wxEVT_PAINT, &wxImagePanel::paintEvent, this);
    

    to the constructor as well.

    1. In the body of MyApp::OnInit, change the line
    frame->SetSizer(sizer);
    

    to

    frame->SetSizerAndFit(sizer);
    

    Using the SetSizerAndFit method will tell the frame to resize itself to the smallest size necessary to display all of its contents. Since in step 1 the minimum size of the image panel was set to the size of image and the image panel is the only content of the frame, the frame will be sized to fit the image.