0

This code reads a picture and put it as background in a window. There are two issues I cannot explain:

  • once you import the picture, clicking the red "X" in the top-right corner doesn't close the window.

  • if you try to drag the image, the program crashes.

Why is it so? Thank you

import wx
import wx.lib.buttons as buttons

class Main(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, id=-1, title=title, size=(300, 300))
        self.initUI()
        self.panel = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, size=(10000, 10000))
        self.backGroundImage=''
        self.Layout()

    def initUI(self):
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        fileMenu.AppendSeparator()

        imp = wx.Menu()
        importBackgroundButton = imp.Append(wx.ID_ANY, 'Import background')
        self.Bind(wx.EVT_MENU, self.OnImportBackground, importBackgroundButton)
        fileMenu.AppendMenu(wx.ID_ANY, 'I&mport', imp)
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)
        self.SetTitle('test')
        self.Centre()
        self.Show(True)

    #load background
    def OnImportBackground(self, e):
        app = wx.App(None)
        style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
        dialog = wx.FileDialog(None, 'Open', wildcard='*.png', style=style)
        if dialog.ShowModal() == wx.ID_OK:
            path = dialog.GetPath()
        else:
            path = None
        dialog.Destroy()
        self.backgroundImage = ButtonImage(self, self.panel, path, (0, 0))
        W = self.backgroundImage.bmp.GetSize()[0]
        H = self.backgroundImage.bmp.GetSize()[1]
        self.SetSize((W+16, H+58))
        self.Refresh()
        #crash


class ButtonImage():
    def __init__(self, parent, panel, nameImage, pos):
        self.panel = panel
        self.bmp = wx.Bitmap(nameImage, wx.BITMAP_TYPE_ANY)
        self.maxPiecePositionX = self.panel.GetSize()[0] - self.bmp.GetSize()[0]
        self.maxPiecePositionY = self.panel.GetSize()[1] - self.bmp.GetSize()[1]
        self.bmapBtn = wx.BitmapButton(self.panel, id=wx.ID_ANY, bitmap=self.bmp, style=wx.NO_BORDER, pos=pos)
        self.bmapBtn.Bind(wx.EVT_LEFT_DOWN, self.OnClickDown, self.bmapBtn)
        self.bmapBtn.Bind(wx.EVT_LEFT_UP, self.OnClickUp, self.bmapBtn)
        self.bmapBtn.Bind(wx.EVT_MOTION, self.MoveButton, self.bmapBtn)
        self.hold = 0
        self.holdPosition = (0, 0)

    def EnterButton(self, event):
        pass

    def LeaveButton(self, event):
        self.hold = 0

    def OnClickDown(self, event):
        obj = event.GetEventObject()
        self.hold = 1
        self.holdPosition = (event.GetX(), event.GetY())

    def OnClickUp(self, event):
        self.hold = 0

    def MoveButton(self, event):
        deltaX, deltaY = 0, 0
        if self.hold:
            deltaX = event.GetPosition()[0] - self.holdPosition[0]
            deltaY = event.GetPosition()[1] - self.holdPosition[1]
            newPositionX = self.bmapBtn.GetPosition()[0] + deltaX
            newPositionY = self.bmapBtn.GetPosition()[1] + deltaY
            if (0 < newPositionX < self.maxPiecePositionX) and (0 < newPositionY < self.maxPiecePositionY):
                self.bmapBtn.SetPosition((newPositionX, newPositionY))
            else:
                self.holdPosition = self.holdPosition[0] + deltaX, self.holdPosition[1] + deltaY
            self.bmapBtn.Raise()
            self.bmapBtn.Refresh()

app = wx.App()
frame = Main(None, "Test")
frame.Show()
app.MainLoop()
Effe Pelosa
  • 163
  • 1
  • 3
  • 13

1 Answers1

1

This example has so many issues that it would take a long time to explain it. E. g., you create a new ButtonImage, which is essentially a wx.BitmapButton, every time you call OnImportBackground without destroying the old one, stacking up a collection of bitmap buttons without properly layouting them.

But what is driving the nail into the coffin that you instantiate a new wx.App every time OnImportBackground is called. If you remove this line (which is completely pointless), the frame can at least be closed.

But to see for "the right way (TM)" to do it, look at this stackoverflow post.

Community
  • 1
  • 1
nepix32
  • 3,012
  • 2
  • 14
  • 29
  • ahh.. that was it. The instantiations of wx.App! I really missed that. Thanks a lot. Re the stacking of backgrounds: it's a "feature" :) I stripped down the code keeping only the essential for a working version for stackoverflow.. – Effe Pelosa Nov 05 '15 at 11:31