Search code examples
imagewxpython

wxPython ImageViewer


I am to create a simple image viewer using wxPython. I am using a panel and a button upon which by clicking a picture would be shown from a directory (Images). Below is the code. I have taken pieces from different websites.

My question is if I maximize the window, the picture viewer as well as the button remain same. I want the picture viewer to increase as well.

Another thing is, after I press the "Load" button, it moves to the left. How do I fix these two problems?

I understand for those 2 above questions, this so big program might be unnecessary. I am a newbie to Python.

Thanks in advance.

import wx, os

class Panel1(wx.Panel):
    def __init__(self, *args, **kwds):
        wx.Panel.__init__(self, *args, **kwds)
        self.jpgs = self.GetJpgList("./Images")
        self.CurrentJpg = 0
        self.MaxImageSize = 200
        self.img = wx.EmptyImage(self.MaxImageSize,self.MaxImageSize)
        self.imageCtrl = wx.StaticBitmap(self, wx.ID_ANY, wx.BitmapFromImage(self.img))
        self.button_1 = wx.Button(self, wx.ID_ANY, "Load")
        self.Bind(wx.EVT_BUTTON, self.OnLoad, self.button_1)
        self.__do_layout()
        self.Layout()

    def GetJpgList(self, dir):
        jpgs = [f for f in os.listdir(dir) if f[-4:] == ".JPG"]
        return [os.path.join(dir, f) for f in jpgs]

    def __do_layout(self):
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add((1,1),1)
        sizer_1.Add(self.imageCtrl, 0, wx.ALL|wx.EXPAND, 5)
        sizer_1.Add((1,1),1)
        sizer_1.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.ALL|wx.EXPAND, 5)
        sizer_2.Add(self.button_1, 0, wx.ALL|wx.TOP, 5)
        sizer_1.Add(sizer_2, 0, wx.ALL, 5)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)

    def OnNext(self, event):
        path = self.jpgs[self.CurrentJpg]
        self.Img = wx.Image(path, wx.BITMAP_TYPE_ANY)
        W = self.Img.GetWidth()
        H = self.Img.GetHeight()
        if W > H:
            NewW = self.MaxImageSize
            NewH = self.MaxImageSize * H / W
        else:
            NewH = self.MaxImageSize
            NewW = self.MaxImageSize * W / H
        self.Img = self.Img.Scale(NewW,NewH)
        self.imageCtrl.SetBitmap(wx.BitmapFromImage(self.Img))
        #self.Fit()
        #self.Layout()
        self.Refresh()

        self.CurrentJpg += 1
        if self.CurrentJpg > len(self.jpgs) -1:
            self.CurrentJpg = 0

# end of class Panel1

class Frame1(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.__set_properties()
        self.__do_layout()

    def __set_properties(self):
        self.SetTitle("Picture")

    def __do_layout(self):
        panel1 = Panel1(self)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(panel1, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)
        self.Layout()
        self.Centre()

# end of class Frame1

class Game1(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame1 = Frame1(None, wx.ID_ANY, "")
        self.SetTopWindow(frame1)
        frame1.Show()
        return 1

# end of class Game1

if __name__ == "__main__":
    game1 = Game1(0)
    game1.MainLoop()

Solution

  • To make the image resize itself on maximize, you will need to catch wx.EVT_MAXIMIZE. Then in your event handler, you'll need to call your function that updates the image control you created. You may need to use the Frame's size to help you determine what your MaxImageSize should be.

    For the load button issue, you may need to call the sizer or the widget's parent's Layout() method.