1

I have MyPanel of size (1200,800) which is embedded in a parent MainPanel (whose size can change with the size of the MainFrame) :

import wx

class MyPanel(wx.Panel):   # panel embedded in the main panel
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, size=(1200,800))
        sizer = wx.BoxSizer(wx.VERTICAL)
        bmp = wx.BitmapFromImage(wx.Image('background.png', wx.BITMAP_TYPE_PNG))  
        myimg = wx.StaticBitmap(self, -1, bmp)
        sizer.Add(myimg, 0, wx.SHAPED, 10)

class MainPanel(wx.Panel):   # main panel embedded in the main frame
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)
        self.mypanel = MyPanel(self)

class MainFrame(wx.Frame):  # main frame window
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, size=(800,600))
        self.panel = MainPanel(self)
        self.Show()

app = wx.App(0)
frame = MainFrame(None, 'Test')
app.MainLoop()

How is it possible to automatically rescale MyPanel so that it fits in the parent MainPanel , keeping its aspect ratio ?

Remark : I am looking for a behaviour close to Windows's standard photo viewer : when the window is resized, the image is rescaled to fit in the parent window.

enter image description here

Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

2

Just apply my previous answer to the panel that you want to maintain the aspect ration on. Not a 100% clear on the exact behavior you want but this should get you close enough.

import wx

    class MyPanel(wx.Panel):   # panel embedded in the main panel
        def __init__(self, parent):
            wx.Panel.__init__(self, parent, -1)
            sizer = wx.BoxSizer(wx.VERTICAL)
            txt = wx.StaticText(self, label="Missing Bitmap");
            sizer.Add(txt, 0, wx.SHAPED, 10)

            self.SetInitialSize((1200, 800))
            self.BackgroundColour = wx.RED
            self.Sizer = sizer

            self.Bind(wx.EVT_SIZE, self.OnSize)

        def OnSize(self, evt):
            hsize = evt.Size[0] * 0.75 # Constrain max height to 75% of width
            self.SetSizeHints(-1, hsize, maxH=hsize)
            evt.Skip()

Important part is here, you need to adjust the size hints on the sub panel window every time its size is being requested to change to tell the sizer to limit the constraints on the geometry of the window.

    class MainPanel(wx.Panel):   # main panel embedded in the main frame
        def __init__(self, parent):
            wx.Panel.__init__(self, parent, -1)
            self.mypanel = MyPanel(self)

            self.BackgroundColour = wx.BLACK

Background color set to help show difference between parent panel and its child panel which is colored red.

            vsizer = wx.BoxSizer(wx.VERTICAL)
            vsizer.AddStretchSpacer(0)
            vsizer.Add(self.mypanel, 1, wx.SHAPED|wx.EXPAND|wx.ALIGN_CENTER)
            vsizer.AddStretchSpacer(0)

            hsizer = wx.BoxSizer(wx.HORIZONTAL)
            hsizer.AddStretchSpacer(0)
            hsizer.Add(vsizer, 1, wx.EXPAND|wx.ALIGN_CENTER)
            hsizer.AddStretchSpacer(0)

            self.Sizer = hsizer;

Here in the MainPanel it uses two sizers with stretch spacers to keep the subpanel pushed towards the middle both horizontally and vertically as the window resizes.

    class MainFrame(wx.Frame):  # main frame window
        def __init__(self, parent, title):
            wx.Frame.__init__(self, parent, -1, title, size=(800,600))
            self.panel = MainPanel(self)
            self.Show()

    app = wx.App(0)
    frame = MainFrame(None, 'Test')
    app.MainLoop()
codeman
  • 48
  • 5
  • What I'm looking for is a behaviour close to Windows's standard photo viewer : http://res1.windows.microsoft.com/resbox/en/windows%207/main/7eaf462a-86dd-42d2-a789-7413f5472dae_63.jpg. When you resize this window, the image is rescaled to fit in the parent window. – Basj Jan 24 '14 at 17:02
  • You should be able to do a little homework and adjust the above sample to get what your looking for. If you want the image to rescale you will have to do the drawing and image sizing calculations yourself and redraw the image to fit the new canvas size in the EVT_PAINT handler of your canvas. StaticBitmaps are "static" and don't resize. – codeman Jan 24 '14 at 18:40
  • Thanks. In fact I will have dozains of images and bitmapbuttons in this panel, that s why i wanted to see if there was an automatic method for rescaling a panel and all its children. – Basj Jan 24 '14 at 19:46
  • You can use the panel as a canvas and get the resizing but you will have to draw the images onto the panel yourself. You may want to look at the image browser control that is in wx.lib for some examples. The source for the module will be in your Python site-packages folder on your machine. – codeman Jan 24 '14 at 21:43
  • I added another question @codeman to explain a bit more what I'm looking for : http://stackoverflow.com/questions/21351282/wxpython-for-image-and-buttons-resizable – Basj Jan 25 '14 at 13:50
1

You need to be using sizers for this type of thing, and if you are then using wx.SHAPED in the sizer.Add flags will maintain the aspect ratio as the size is changed.

tom10
  • 67,082
  • 10
  • 127
  • 137
  • I have completed reformulated the question @tom10, would you have an example of code ? – Basj Jan 24 '14 at 14:46