• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 819
  • Last Modified:

Load an image into a wx.BoxSizer

Hi all,

I am trying to make up a very basic interface for viewing an image. The layout of the GUI will be something like this: http://danpearce.co.uk/gui.png

While I understand how sizers work for basic GUI, I'm struggling to work out how to make this work with an image. I've found several examples but these seem to mainly display an image over the entire frame.

Can this be done by loading an image into a box sizer or is there a better method? Any direction to a worked example or tutorial would be greatly appreciated. Images are always the same size if it makes any difference.

Thanks in advance for your time,

Dan
0
devondan
Asked:
devondan
  • 4
  • 2
1 Solution
 
peprCommented:
Have a look at the example below and ask the questions. The panels are not fine tuned -- just to show principle. The code for the ImageWindow was borrowed (see url in the comment). The image has the fixed name here.
import wx

class ImageWindow(wx.Window):
    "The code of the class taken from http://aspn.activestate.com/ASPN/Mail/Message/wxpython-users/628818"
    
    def __init__(self, parent, id):
        wx.Window.__init__(self, parent, id)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.image = None


    def SetImage(self, image):
        self.image = image
        self.Refresh(True)


    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        if self.image:
            dc.DrawBitmap(self.image.ConvertToBitmap(), 0, 0, False)


class AppFrame(wx.Frame):
    
    def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):

        wx.Frame.__init__(self, parent, ID, title, pos, size, style)

        # Build the panels with buttons and other controls.
        vbox = wx.BoxSizer(wx.VERTICAL)
        topBox = wx.BoxSizer(wx.HORIZONTAL)  # the left for controls, the right for image
        botBox = wx.BoxSizer(wx.HORIZONTAL)  # the bottom for buttons
        vbox.Add(topBox, 1, wx.EXPAND)
        vbox.Add(botBox)
        
        # Some buttons added to the bottom part of the window.
        btnA = wx.Button(self, wx.ID_ANY, 'Button A')
        btnB = wx.Button(self, wx.ID_ANY, 'Button B')
        btnC = wx.Button(self, wx.ID_ANY, 'Button C')
        btnD = wx.Button(self, wx.ID_ANY, 'Button D')
        botBox.Add(btnA)
        botBox.Add(btnB)
        botBox.Add(btnC)
        botBox.Add(btnD)
        
        # Vertical box for left controls (here the buttons).
        leftBox = wx.BoxSizer(wx.VERTICAL)
        btn1 = wx.Button(self, wx.ID_ANY, 'Button 1')
        btn2 = wx.Button(self, wx.ID_ANY, 'Button 2')
        
        leftBox.Add(btn1)
        leftBox.Add(btn2)
        
        topBox.Add(leftBox)  # Left box added to the top box.
        
        # Image window created and added to the top box (a second box, after the left box)
        imageWindow = ImageWindow(self, wx.ID_ANY)
        topBox.Add(imageWindow, 1, wx.EXPAND) # vertically and horizontally stretchable

        # Image loaded and set to the image window.
        image = wx.Image('image.png', wx.BITMAP_TYPE_PNG)
        imageWindow.SetImage(image)
        
        # Set the vbox as the top sizer.
        self.SetSizer(vbox)
        
        
class MyApplication(wx.App):

    def OnInit(self):
        wnd = AppFrame(None, wx.ID_ANY, "Main application window -- title")
        wnd.Show(True)
        return True

        
def main():
    app = MyApplication(False)
    app.MainLoop()    


if __name__ == "__main__":
    main()

Open in new window

image.png
0
 
peprCommented:
You should observe something like that on the screen (here with console window at the background, on Windows).
captured.png
0
 
devondanAuthor Commented:
Greatly appreciated example. Thank you very much for your time.

Dan
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 
peprCommented:
Man, you are fast!  (Thanks for the point ;)

Feel free to continue this question when asking for details.

Petr
0
 
devondanAuthor Commented:
I've been quite actively waiting for a response to this one. I had the theory right but was just lacking that example that provides a working base to learn from. This is exactly what I was looking for.

Thanks again and for the offer of any additional help.

Dan
0
 
peprCommented:
The key idea to understand (in my opinion) is that box sizers are structures separated from the abstraction of windows. They are used only for calculation of geometry... However, they make sense only when some windows (controls) are organized via them. This way, you always have to have some objects derived from the wx.Window base class (here the buttons and the ImageWindow).

The wx.Bitmap class object is not capable to display itself. There is a class wx.StaticBitmap; however, it was not designed for displaying big images (rather icons or such). It is more suitable to draw it via the device context of another window.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now