How to construct simple wxWidgets image display

10,770

Solution 1

Don't let the size of the "image" sample fool you, only a few lines of code are necessary to do what you want.

Search for the MyImageFrame class in the image.cpp file, it is nothing more than a class with a private bitmap field, a custom constructor to set the bitmap and the window client size, and an event handler for EVT_PAINT:

void OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc( this );
    dc.DrawBitmap( m_bitmap, 0, 0, true /* use mask */ );
}

Since you don't want a frame class here's your recipe: You create a simple descendant of wxWindow that has a similar constructor, paint handler and duplicates the methods of wxStaticBitmap that you use in your code. Maybe simply one method to set a new bitmap and resize the control to the new bitmap dimensions.

Solution 2

// A scrolled window for showing an image.
class PictureFrame: public wxScrolledWindow
{   
public:
    PictureFrame()
        : wxScrolledWindow()
        , bitmap(0,0)
    {;}

    void Create(wxWindow *parent, wxWindowID id = -1)
    {
        wxScrolledWindow::Create(parent, id);
    }

    void LoadImage(wxImage &image) {
        bitmap = wxBitmap(image);
        SetVirtualSize(bitmap.GetWidth(), bitmap.GetHeight());
        wxClientDC dc(this);
        PrepareDC(dc);
        dc.DrawBitmap(bitmap, 0, 0);
    }

protected:
    wxBitmap bitmap;

    void OnMouse(wxMouseEvent &event) {
        int xx,yy;
        CalcUnscrolledPosition(event.GetX(), event.GetY(), &xx, &yy);
        event.m_x = xx; event.m_y = yy;
        event.ResumePropagation(1); // Pass along mouse events (e.g. to parent)
        event.Skip();
    }

    void OnPaint(wxPaintEvent &event) {
        wxPaintDC dc(this);
        PrepareDC(dc);
        dc.DrawBitmap(bitmap, 0,0, true);
    }
private:
    DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(PictureFrame,wxScrolledWindow)
    EVT_PAINT(PictureFrame::OnPaint)
    EVT_MOUSE_EVENTS(PictureFrame::OnMouse)
END_EVENT_TABLE()
Share:
10,770
Jive Dadson
Author by

Jive Dadson

Specializing in system software, such as compilers and runtime support, both general and application-specific, and in realtime programming, particularly for robotics motion control. Experienced in statistical modeling, numerical optimization, and simulation. Interested in color theory and imaging software. ["Jive Dadson" is an anagram for "David Jones", which is not a great search term.]

Updated on June 25, 2022

Comments

  • Jive Dadson
    Jive Dadson about 2 years

    I wrote a wxPython program that I am translating to wxWidgets. The program has a scrolled window that displays an image. Following Rappin, wxPython In Action (Listing 12.1), I used a StaticBitmap within a panel. While surfing the latest wxWidgets documentation, I found a dire warning that wxStaticBitmap should only be used for very small images. It says, "... you should use your own control if you want to display larger images portably." Okay. Show me. I don't have my "own control."

    Was Rappin wrong, or is the documentation out of date?

    The question - a newbie one, no doubt - is what is the right way to do a simple image-view window in wxWidgets? A drop-in replacement for wxStaticBitmap would be nice. I looked into the "image" program in the wxWidgets "samples" directory. It's as long a War and Peace. Surely there must be a canned class or a simple recipe.